package.xml0000664000175000017500000070400113210321137013026 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 fundamental and performance-critical components necessary to build a fully-functional MongoDB driver. Jeremy Mikola jmikola jmikola@php.net yes Derick Rethans derick derick@php.net yes Hannes Magnusson bjori bjori@php.net no 2017-12-01 1.3.4 1.3.4 stable stable Apache License ** Bug * [PHPC-1053] - UTCDateTime constructor reports that its single argument is required 5.5.0 7.99.99 1.4.8 mongodb mongodb-1.3.4/scripts/centos/ldap/Domain.ldif0000664000175000017500000000012713210321137020746 0ustar jmikolajmikoladn: dc=10gen,dc=me objectClass: dcObject objectClass: organization dc: 10gen o : 10gen mongodb-1.3.4/scripts/centos/ldap/Users.ldif0000664000175000017500000000010613210321137020635 0ustar jmikolajmikoladn: ou=Users,dc=10gen,dc=me ou: Users objectClass: organizationalUnit mongodb-1.3.4/scripts/centos/ldap/basics.ldif0000664000175000017500000000024413210321137021003 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.3.4/scripts/centos/ldap/install.sh0000664000175000017500000000114113210321137020676 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.3.4/scripts/centos/ldap/ldapconfig.py0000664000175000017500000000375013210321137021364 0ustar jmikolajmikola#!/usr/bin/python import optparse import ldap import ldap.modlist as modlist def main(): parser = optparse.OptionParser(usage="""\ %prog [options] Add users to LDAP """) # add in command line options. Add mongo host/port combo later parser.add_option("-f", "--filename", dest="fname", help="name of file with user names", default=None) (options, args) = parser.parse_args() if options.fname is None: print "\nERROR: Must specify name of file to import\n" sys.exit(-1) # Open a connection l = ldap.initialize("ldap://localhost") # Bind/authenticate with a user with apropriate rights to add objects l.simple_bind_s("cn=Manager,dc=10gen,dc=me","password") for uname in open(options.fname, 'r'): try: # The dn of our new entry/object print "adding ", uname dn= 'uid=' + uname.lower() + ',ou=Users,dc=10gen,dc=me' ldif = configUser(uname.rstrip('\r\n')) # Do the actual synchronous add-operation to the ldapserver l.add_s(dn,ldif) except ldap.LDAPError, e: print e.message['info'] # Its nice to the server to disconnect and free resources when done l.unbind_s() # Do the tld configuration for the ldap tree def configDC(): # A dict to help build the "body" of the object attrs = {} attrs['objectclass'] = ['organization','dcObject'] attrs['dn'] = 'dc=10gen,dc=me' attrs['dc'] = '10gen' attrs['o'] = '10gen' # Convert our dict to nice syntax for the add-function using modlist ldif = modlist.addModlist(attrs) def configOU(): # A dict to help build the "body" of the object attrs = {} attrs['dn'] = 'dc=10gen,dc=me' attrs['objectclass'] = ['organiationalUnit'] attrs['ou'] = 'Users' ldif = modlist.addModlist(attrs) def configUser( uname ): attrs = {} # attrs['dn'] = ['cn=' + uname + 'ou=Users,dc=10gen,dc=me'] attrs['cn'] = [uname] # attrs['uid'] = [uname] attrs['sn'] = 'TestUser' attrs['objectclass'] = ['inetOrgPerson'] attrs['userPassword'] = 'password' return modlist.addModlist(attrs) if __name__ == "__main__": main() mongodb-1.3.4/scripts/centos/ldap/mongod.ldif0000664000175000017500000001027213210321137021024 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.3.4/scripts/centos/ldap/pw.ldif0000664000175000017500000000117313210321137020167 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.3.4/scripts/centos/ldap/saslauthd.conf0000664000175000017500000000014313210321137021534 0ustar jmikolajmikolaldap_servers: ldap://localhost:389 ldap_search_base: ou=Users,dc=10gen,dc=me ldap_filter: (uid=%u) mongodb-1.3.4/scripts/centos/ldap/users0000664000175000017500000000002613210321137017761 0ustar jmikolajmikolabugs features dbadmin mongodb-1.3.4/scripts/centos/essentials.sh0000664000175000017500000000036213210321137020466 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.3.4/scripts/freebsd/essentials.sh0000664000175000017500000000057513210321137020613 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.3.4/scripts/freebsd/phongo.sh0000664000175000017500000000047313210321137017730 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.3.4/scripts/presets/replicaset-30.json0000664000175000017500000000266513210321137021430 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.3.4/scripts/presets/replicaset.json0000664000175000017500000000261713210321137021205 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.3.4/scripts/presets/standalone-24.json0000664000175000017500000000053513210321137021422 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.3.4/scripts/presets/standalone-26.json0000664000175000017500000000053513210321137021424 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.3.4/scripts/presets/standalone-30.json0000664000175000017500000000053513210321137021417 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.3.4/scripts/presets/standalone-auth.json0000664000175000017500000000061013210321137022130 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.3.4/scripts/presets/standalone-plain.json0000664000175000017500000000074613210321137022304 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.3.4/scripts/presets/standalone-ssl.json0000664000175000017500000000101513210321137021770 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.3.4/scripts/presets/standalone-x509.json0000664000175000017500000000125613210321137021703 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.3.4/scripts/presets/standalone.json0000664000175000017500000000046713210321137021203 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.3.4/scripts/ssl/ca.pem0000664000175000017500000000564113210321137016361 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.3.4/scripts/ssl/client.pem0000600000175000017500000000561113210321137017237 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.3.4/scripts/ssl/crl.pem0000664000175000017500000000376513210321137016563 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.3.4/scripts/ssl/server.pem0000664000175000017500000000566513210321137017312 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.3.4/scripts/ubuntu/ldap/install.sh0000664000175000017500000000100613210321137020725 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.3.4/scripts/ubuntu/ldap/saslauthd.conf0000664000175000017500000000015013210321137021561 0ustar jmikolajmikolaldap_servers: ldap://192.168.112.20:389 ldap_search_base: ou=Users,dc=10gen,dc=me ldap_filter: (uid=%u) mongodb-1.3.4/scripts/ubuntu/essentials.sh0000664000175000017500000000036513210321137020520 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.3.4/scripts/ubuntu/mongo-orchestration.sh0000664000175000017500000000327713210321137022354 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.3.4/scripts/ubuntu/phongo.sh0000664000175000017500000000056613210321137017643 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.3.4/scripts/vmware/kernel.sh0000664000175000017500000000046613210321137017607 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.3.4/scripts/convert-bson-corpus-tests.php0000664000175000017500000002667613210321137022306 0ustar jmikolajmikola 'Variation in double\'s string representation (SPEC-850)', 'Double type: -1.23456789012345677E+18' => 'Variation in double\'s string representation (SPEC-850)', 'Int64 type: -1' => 'PHP encodes integers as 32-bit if range allows', 'Int64 type: 0' => 'PHP encodes integers as 32-bit if range allows', 'Int64 type: 1' => 'PHP encodes integers as 32-bit if range allows', 'Javascript Code with Scope: bad scope doc (field has bad string length)' => 'Depends on PHPC-889', 'Javascript Code with Scope: Unicode and embedded null in code string, empty scope' => 'Embedded null in code string is not supported in libbson (CDRIVER-1879)', 'Multiple types within the same document: All BSON types' => 'PHP encodes integers as 32-bit if range allows', 'Top-level document validity: Bad $date (number, not string or hash)' => 'Legacy extended JSON $date syntax uses numbers (CDRIVER-2223)', ]; $outputPath = realpath(__DIR__ . '/../tests') . '/bson-corpus/'; if ( ! is_dir($outputPath) && ! mkdir($outputPath, 0755, true)) { printf("Error creating output path: %s\n", $outputPath); } foreach (array_slice($argv, 1) as $inputFile) { if ( ! is_readable($inputFile) || ! is_file($inputFile)) { printf("Error reading %s\n", $inputFile); continue; } $test = json_decode(file_get_contents($inputFile), true); if (json_last_error() !== JSON_ERROR_NONE) { printf("Error decoding %s: %s\n", $inputFile, json_last_error_msg()); continue; } if ( ! isset($test['description'])) { printf("Skipping test file without \"description\" field: %s\n", $inputFile); continue; } if ( ! empty($test['deprecated'])) { printf("Skipping deprecated test file: %s\n", $inputFile); continue; } if ( ! empty($test['valid'])) { foreach ($test['valid'] as $i => $case) { $outputFile = sprintf('%s-valid-%03d.phpt', pathinfo($inputFile, PATHINFO_FILENAME), $i + 1); try { $output = renderPhpt(getParamsForValid($test, $case), $expectedFailures); } catch (Exception $e) { printf("Error processing valid[%d] in %s: %s\n", $i, $inputFile, $e->getMessage()); continue; } if (false === file_put_contents($outputPath . '/' . $outputFile, $output)) { printf("Error writing valid[%d] in %s\n", $i, $inputFile); continue; } } } if ( ! empty($test['decodeErrors'])) { foreach ($test['decodeErrors'] as $i => $case) { $outputFile = sprintf('%s-decodeError-%03d.phpt', pathinfo($inputFile, PATHINFO_FILENAME), $i + 1); try { $output = renderPhpt(getParamsForDecodeError($test, $case), $expectedFailures); } catch (Exception $e) { printf("Error processing decodeErrors[%d] in %s: %s\n", $i, $inputFile, $e->getMessage()); continue; } if (false === file_put_contents($outputPath . '/' . $outputFile, $output)) { printf("Error writing decodeErrors[%d] in %s\n", $i, $inputFile); continue; } } } if ( ! empty($test['parseErrors'])) { foreach ($test['parseErrors'] as $i => $case) { $outputFile = sprintf('%s-parseError-%03d.phpt', pathinfo($inputFile, PATHINFO_FILENAME), $i + 1); try { $output = renderPhpt(getParamsForParseError($test, $case), $expectedFailures); } catch (Exception $e) { printf("Error processing parseErrors[%d] in %s: %s\n", $i, $inputFile, $e->getMessage()); continue; } if (false === file_put_contents($outputPath . '/' . $outputFile, $output)) { printf("Error writing parseErrors[%d] in %s\n", $i, $inputFile); continue; } } } } function getParamsForValid(array $test, array $case) { foreach (['description', 'canonical_bson', 'canonical_extjson'] as $field) { if (!isset($case[$field])) { throw new InvalidArgumentException(sprintf('Missing "%s" field', $field)); } } $code = ''; $expect = ''; $lossy = isset($case['lossy']) ? (boolean) $case['lossy'] : false; $canonicalBson = $case['canonical_bson']; $expectedCanonicalBson = strtolower($canonicalBson); $code .= sprintf('$canonicalBson = hex2bin(%s);', var_export($canonicalBson, true)) . "\n"; if (isset($case['degenerate_bson'])) { $degenerateBson = $case['degenerate_bson']; $expectedDegenerateBson = strtolower($degenerateBson); $code .= sprintf('$degenerateBson = hex2bin(%s);', var_export($degenerateBson, true)) . "\n"; } if (isset($case['converted_bson'])) { $convertedBson = $case['converted_bson']; $expectedConvertedBson = strtolower($convertedBson); $code .= sprintf('$convertedBson = hex2bin(%s);', var_export($convertedBson, true)) . "\n"; } $canonicalExtJson = $case['canonical_extjson']; $expectedCanonicalExtJson = json_canonicalize($canonicalExtJson); $code .= sprintf('$canonicalExtJson = %s;', var_export($canonicalExtJson, true)) . "\n"; if (isset($case['relaxed_extjson'])) { $relaxedExtJson = $case['relaxed_extjson']; $expectedRelaxedExtJson = json_canonicalize($relaxedExtJson); $code .= sprintf('$relaxedExtJson = %s;', var_export($relaxedExtJson, true)) . "\n"; } if (isset($case['degenerate_extjson'])) { $degenerateExtJson = $case['degenerate_extjson']; $expectedDegenerateExtJson = json_canonicalize($degenerateExtJson); $code .= sprintf('$degenerateExtJson = %s;', var_export($degenerateExtJson, true)) . "\n"; } if (isset($case['converted_extjson'])) { $convertedExtJson = $case['converted_extjson']; $expectedConvertedExtJson = json_canonicalize($convertedExtJson); $code .= sprintf('$convertedExtJson = %s;', var_export($convertedExtJson, true)) . "\n"; } $code .= "\n// Canonical BSON -> Native -> Canonical BSON \n"; $code .= 'echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n";' . "\n"; $expect .= $expectedCanonicalBson . "\n"; $code .= "\n// Canonical BSON -> Canonical extJSON \n"; $code .= 'echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n";' . "\n";; $expect .= $expectedCanonicalExtJson . "\n"; if (isset($relaxedExtJson)) { $code .= "\n// Canonical BSON -> Relaxed extJSON \n"; $code .= 'echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n";' . "\n";; $expect .= $expectedRelaxedExtJson . "\n"; } if (!$lossy) { $code .= "\n// Canonical extJSON -> Canonical BSON \n"; $code .= 'echo bin2hex(fromJSON($canonicalExtJson)), "\n";' . "\n"; $expect .= $expectedCanonicalBson . "\n"; } if (isset($degenerateBson)) { $code .= "\n// Degenerate BSON -> Native -> Canonical BSON \n"; $code .= 'echo bin2hex(fromPHP(toPHP($degenerateBson))), "\n";' . "\n"; $expect .= $expectedCanonicalBson . "\n"; $code .= "\n// Degenerate BSON -> Canonical extJSON \n"; $code .= 'echo json_canonicalize(toCanonicalExtendedJSON($degenerateBson)), "\n";' . "\n";; $expect .= $expectedCanonicalExtJson . "\n"; if (isset($relaxedExtJson)) { $code .= "\n// Degenerate BSON -> Relaxed extJSON \n"; $code .= 'echo json_canonicalize(toRelaxedExtendedJSON($degenerateBson)), "\n";' . "\n";; $expect .= $expectedRelaxedExtJson . "\n"; } } if (isset($degenerateExtJson) && !$lossy) { $code .= "\n// Degenerate extJSON -> Canonical BSON \n"; $code .= 'echo bin2hex(fromJSON($degenerateExtJson)), "\n";' . "\n"; $expect .= $expectedCanonicalBson . "\n"; } if (isset($relaxedExtJson)) { $code .= "\n// Relaxed extJSON -> BSON -> Relaxed extJSON \n"; $code .= 'echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n";' . "\n"; $expect .= $expectedRelaxedExtJson . "\n"; } return [ '%NAME%' => sprintf('%s: %s', trim($test['description']), trim($case['description'])), '%CODE%' => trim($code), '%EXPECT%' => trim($expect), ]; } function getParamsForDecodeError(array $test, array $case) { foreach (['description', 'bson'] as $field) { if (!isset($case[$field])) { throw new InvalidArgumentException(sprintf('Missing "%s" field', $field)); } } $code = sprintf('$bson = hex2bin(%s);', var_export($case['bson'], true)) . "\n\n"; $code .= "throws(function() use (\$bson) {\n"; $code .= " var_dump(toPHP(\$bson));\n"; $code .= "}, 'MongoDB\Driver\Exception\UnexpectedValueException');"; /* We do not test for the exception message, since that may differ based on * the nature of the decoding error. */ $expect = "OK: Got MongoDB\Driver\Exception\UnexpectedValueException"; return [ '%NAME%' => sprintf('%s: %s', trim($test['description']), trim($case['description'])), '%CODE%' => trim($code), '%EXPECT%' => trim($expect), ]; } function getParamsForParseError(array $test, array $case) { foreach (['description', 'string'] as $field) { if (!isset($case[$field])) { throw new InvalidArgumentException(sprintf('Missing "%s" field', $field)); } } $code = ''; $expect = ''; switch ($test['bson_type']) { case '0x00': // Top-level document $code = "throws(function() {\n"; $code .= sprintf(" fromJSON(%s);\n", var_export($case['string'], true)); $code .= "}, 'MongoDB\Driver\Exception\UnexpectedValueException');"; /* We do not test for the exception message, since that may differ * based on the nature of the parse error. */ $expect = "OK: Got MongoDB\Driver\Exception\UnexpectedValueException"; break; case '0x13': // Decimal128 $code = "throws(function() {\n"; $code .= sprintf(" new MongoDB\BSON\Decimal128(%s);\n", var_export($case['string'], true)); $code .= "}, 'MongoDB\Driver\Exception\InvalidArgumentException');"; /* We do not test for the exception message, since that may differ * based on the nature of the parse error. */ $expect = "OK: Got MongoDB\Driver\Exception\InvalidArgumentException"; break; default: throw new UnexpectedValueException(sprintf("Parse errors not supported for BSON type: %s", $test['bson_type'])); } return [ '%NAME%' => sprintf('%s: %s', trim($test['description']), trim($case['description'])), '%CODE%' => trim($code), '%EXPECT%' => trim($expect), ]; } function renderPhpt(array $params, array $expectedFailures) { $params['%XFAIL%'] = isset($expectedFailures[$params['%NAME%']]) ? "--XFAIL--\n" . $expectedFailures[$params['%NAME%']] . "\n" : ''; $template = <<< 'TEMPLATE' --TEST-- %NAME% %XFAIL%--DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- %EXPECT% ===DONE=== TEMPLATE; return str_replace(array_keys($params), array_values($params), $template); } mongodb-1.3.4/scripts/convert-mo-tests.php0000664000175000017500000002130513210321137020427 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.3.4/scripts/list-servers.php0000664000175000017500000000034013210321137017634 0ustar jmikolajmikola $uri) { printf("%-20s \t %s\n", $serverid, $uri); } mongodb-1.3.4/scripts/run-tests-on.sh0000664000175000017500000000046113210321137017377 0ustar jmikolajmikola#!/bin/sh VMNAME=$1 vagrant status $VMNAME | grep -q "$VMNAME.*running" if test $? -eq 0; then vagrant provision $VMNAME > .$VMNAME else vagrant up $VMNAME > .$VMNAME fi cat .tests | grep -q -E "FAIL|WARN" if test $? -eq 0; then echo "$VMNAME FAILED" cat .tests exit 2 else echo "$VMNAME OK" fi mongodb-1.3.4/scripts/start-servers.php0000664000175000017500000002037013210321137020023 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.3.4/src/BSON/Binary.c0000664000175000017500000003633113210321137015723 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" #define PHONGO_BINARY_UUID_SIZE 16 zend_class_entry *php_phongo_binary_ce; /* Initialize the object and return whether it was successful. An exception will * be thrown on error. */ static bool php_phongo_binary_init(php_phongo_binary_t *intern, const char *data, phongo_zpp_char_len data_len, phongo_long type TSRMLS_DC) /* {{{ */ { 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 false; } if ((type == BSON_SUBTYPE_UUID_DEPRECATED || type == BSON_SUBTYPE_UUID) && data_len != PHONGO_BINARY_UUID_SIZE) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected UUID length to be %d bytes, %d given", PHONGO_BINARY_UUID_SIZE, data_len); return false; } intern->data = estrndup(data, data_len); intern->data_len = data_len; intern->type = (uint8_t) type; return true; } /* }}} */ /* Initialize the object from a HashTable and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_binary_init_from_hash(php_phongo_binary_t *intern, HashTable *props TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *data, *type; if ((data = zend_hash_str_find(props, "data", sizeof("data")-1)) && Z_TYPE_P(data) == IS_STRING && (type = zend_hash_str_find(props, "type", sizeof("type")-1)) && Z_TYPE_P(type) == IS_LONG) { return php_phongo_binary_init(intern, Z_STRVAL_P(data), Z_STRLEN_P(data), Z_LVAL_P(type) TSRMLS_CC); } #else zval **data, **type; if (zend_hash_find(props, "data", sizeof("data"), (void**) &data) == SUCCESS && Z_TYPE_PP(data) == IS_STRING && zend_hash_find(props, "type", sizeof("type"), (void**) &type) == SUCCESS && Z_TYPE_PP(type) == IS_LONG) { return php_phongo_binary_init(intern, Z_STRVAL_PP(data), Z_STRLEN_PP(data), Z_LVAL_PP(type) TSRMLS_CC); } #endif phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"data\" string and \"type\" integer fields", ZSTR_VAL(php_phongo_binary_ce->name)); return false; } /* }}} */ /* {{{ proto void MongoDB\BSON\Binary::__construct(string $data, int $type) Construct a new BSON binary type */ static 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); php_phongo_binary_init(intern, data, data_len, type TSRMLS_CC); } /* }}} */ /* {{{ proto void MongoDB\BSON\Binary::__set_state(array $properties) */ static PHP_METHOD(Binary, __set_state) { php_phongo_binary_t *intern; HashTable *props; zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_binary_ce); intern = Z_BINARY_OBJ_P(return_value); props = Z_ARRVAL_P(array); php_phongo_binary_init_from_hash(intern, props TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\Binary::__toString() Return the Binary's data string. */ static PHP_METHOD(Binary, __toString) { php_phongo_binary_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_BINARY_OBJ_P(getThis()); PHONGO_RETURN_STRINGL(intern->data, intern->data_len); } /* }}} */ /* {{{ proto string MongoDB\BSON\Binary::getData() */ static 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 MongoDB\BSON\Binary::getType() */ static 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); } /* }}} */ /* {{{ proto array MongoDB\BSON\Binary::jsonSerialize() */ static PHP_METHOD(Binary, jsonSerialize) { php_phongo_binary_t *intern; char type[3]; int type_len; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_BINARY_OBJ_P(getThis()); array_init_size(return_value, 2); #if PHP_VERSION_ID >= 70000 { zend_string *data = php_base64_encode((unsigned char *)intern->data, intern->data_len); ADD_ASSOC_STRINGL(return_value, "$binary", ZSTR_VAL(data), ZSTR_LEN(data)); zend_string_free(data); } #else { int data_len = 0; unsigned char *data = php_base64_encode((unsigned char *)intern->data, intern->data_len, &data_len); ADD_ASSOC_STRINGL(return_value, "$binary", (char *)data, data_len); efree(data); } #endif type_len = snprintf(type, sizeof(type), "%02x", intern->type); ADD_ASSOC_STRINGL(return_value, "$type", type, type_len); } /* }}} */ /* {{{ proto string MongoDB\BSON\Binary::serialize() */ static PHP_METHOD(Binary, serialize) { php_phongo_binary_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval *retval; #endif php_serialize_data_t var_hash; smart_str buf = { 0 }; intern = Z_BINARY_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } #if PHP_VERSION_ID >= 70000 array_init_size(&retval, 2); ADD_ASSOC_STRINGL(&retval, "data", intern->data, intern->data_len); ADD_ASSOC_LONG_EX(&retval, "type", intern->type); #else ALLOC_INIT_ZVAL(retval); array_init_size(retval, 2); ADD_ASSOC_STRINGL(retval, "data", intern->data, intern->data_len); ADD_ASSOC_LONG_EX(retval, "type", intern->type); #endif PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC); smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); PHONGO_RETVAL_SMART_STR(buf); smart_str_free(&buf); zval_ptr_dtor(&retval); } /* }}} */ /* {{{ proto void MongoDB\BSON\Binary::unserialize(string $serialized) */ static PHP_METHOD(Binary, unserialize) { php_phongo_binary_t *intern; zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; #if PHP_VERSION_ID >= 70000 zval props; #else zval *props; #endif php_unserialize_data_t var_hash; intern = Z_BINARY_OBJ_P(getThis()); zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); #if PHP_VERSION_ID < 70000 ALLOC_INIT_ZVAL(props); #endif PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&props); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_binary_ce->name)); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #if PHP_VERSION_ID >= 70000 php_phongo_binary_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC); #else php_phongo_binary_init_from_hash(intern, HASH_OF(props) TSRMLS_CC); #endif zval_ptr_dtor(&props); } /* }}} */ /* {{{ MongoDB\BSON\Binary function entries */ 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___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Binary_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Binary_void, 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, __set_state, ai_Binary___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Binary, __toString, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Binary, jsonSerialize, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Binary, serialize, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Binary, unserialize, ai_Binary_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Binary, getData, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Binary, getType, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\Binary object handlers */ static zend_object_handlers php_phongo_handler_binary; 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 (intern->properties) { zend_hash_destroy(intern->properties); FREE_HASHTABLE(intern->properties); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static int php_phongo_binary_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_binary_t *intern1, *intern2; intern1 = Z_BINARY_OBJ_P(o1); intern2 = Z_BINARY_OBJ_P(o2); /* MongoDB compares binary types first by the data length, then by the type * byte, and finally by the binary data itself. */ if (intern1->data_len != intern2->data_len) { return intern1->data_len < intern2->data_len ? -1 : 1; } if (intern1->type != intern2->type) { return intern1->type < intern2->type ? -1 : 1; } return zend_binary_strcmp(intern1->data, intern1->data_len, intern2->data, intern2->data_len); } /* }}} */ static HashTable *php_phongo_binary_get_gc(zval *object, phongo_get_gc_table table, int *n TSRMLS_DC) /* {{{ */ { *table = NULL; *n = 0; return Z_BINARY_OBJ_P(object)->properties; } /* }}} */ static HashTable *php_phongo_binary_get_properties_hash(zval *object, bool is_debug TSRMLS_DC) /* {{{ */ { php_phongo_binary_t *intern; HashTable *props; intern = Z_BINARY_OBJ_P(object); PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2); if (!intern->data) { return props; } #if PHP_VERSION_ID >= 70000 { zval data, type; ZVAL_STRINGL(&data, intern->data, intern->data_len); zend_hash_str_update(props, "data", sizeof("data")-1, &data); ZVAL_LONG(&type, intern->type); zend_hash_str_update(props, "type", sizeof("type")-1, &type); } #else { zval *data, *type; MAKE_STD_ZVAL(data); ZVAL_STRINGL(data, intern->data, intern->data_len, 1); zend_hash_update(props, "data", sizeof("data"), &data, sizeof(data), NULL); MAKE_STD_ZVAL(type); ZVAL_LONG(type, intern->type); zend_hash_update(props, "type", sizeof("type"), &type, sizeof(type), NULL); } #endif return props; } /* }}} */ static HashTable *php_phongo_binary_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { *is_temp = 1; return php_phongo_binary_get_properties_hash(object, true TSRMLS_CC); } /* }}} */ static HashTable *php_phongo_binary_get_properties(zval *object TSRMLS_DC) /* {{{ */ { return php_phongo_binary_get_properties_hash(object, false TSRMLS_CC); } /* }}} */ /* }}} */ void php_phongo_binary_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_binary_ce); zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_binary_interface_ce); zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, zend_ce_serializable); memcpy(&php_phongo_handler_binary, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_binary.compare_objects = php_phongo_binary_compare_objects; php_phongo_handler_binary.get_debug_info = php_phongo_binary_get_debug_info; php_phongo_handler_binary.get_gc = php_phongo_binary_get_gc; php_phongo_handler_binary.get_properties = php_phongo_binary_get_properties; #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); } /* }}} */ /* * 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.3.4/src/BSON/BinaryInterface.c0000664000175000017500000000312413210321137017536 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_binary_interface_ce; /* {{{ MongoDB\BSON\BinaryInterface function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_BinaryInterface_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_binary_interface_me[] = { ZEND_ABSTRACT_ME(BinaryInterface, getData, ai_BinaryInterface_void) ZEND_ABSTRACT_ME(BinaryInterface, getType, ai_BinaryInterface_void) ZEND_ABSTRACT_ME(BinaryInterface, __toString, ai_BinaryInterface_void) PHP_FE_END }; /* }}} */ void php_phongo_binary_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "BinaryInterface", php_phongo_binary_interface_me); php_phongo_binary_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/Decimal128.c0000664000175000017500000002752513210321137016275 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_decimal128_ce; /* Initialize the object and return whether it was successful. An exception will * be thrown on error. */ static bool php_phongo_decimal128_init(php_phongo_decimal128_t *intern, const char *value TSRMLS_DC) /* {{{ */ { if (!bson_decimal128_from_string(value, &intern->decimal)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing Decimal128 string: %s", value); return false; } intern->initialized = true; return true; } /* }}} */ /* Initialize the object from a HashTable and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_decimal128_init_from_hash(php_phongo_decimal128_t *intern, HashTable *props TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *dec; if ((dec = zend_hash_str_find(props, "dec", sizeof("dec")-1)) && Z_TYPE_P(dec) == IS_STRING) { return php_phongo_decimal128_init(intern, Z_STRVAL_P(dec) TSRMLS_CC); } #else zval **dec; if (zend_hash_find(props, "dec", sizeof("dec"), (void**) &dec) == SUCCESS && Z_TYPE_PP(dec) == IS_STRING) { return php_phongo_decimal128_init(intern, Z_STRVAL_PP(dec) TSRMLS_CC); } #endif phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"dec\" string field", ZSTR_VAL(php_phongo_decimal128_ce->name)); return false; } /* }}} */ /* {{{ proto void MongoDB\BSON\Decimal128::__construct(string $value) Construct a new BSON Decimal128 type */ static PHP_METHOD(Decimal128, __construct) { php_phongo_decimal128_t *intern; zend_error_handling error_handling; char *value; phongo_zpp_char_len value_len; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_DECIMAL128_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); php_phongo_decimal128_init(intern, value TSRMLS_CC); } /* }}} */ /* {{{ proto void MongoDB\BSON\Decimal128::__set_state(array $properties) */ static PHP_METHOD(Decimal128, __set_state) { php_phongo_decimal128_t *intern; HashTable *props; zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_decimal128_ce); intern = Z_DECIMAL128_OBJ_P(return_value); props = Z_ARRVAL_P(array); php_phongo_decimal128_init_from_hash(intern, props TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\Decimal128::__toString() */ static PHP_METHOD(Decimal128, __toString) { php_phongo_decimal128_t *intern; char outbuf[BSON_DECIMAL128_STRING]; intern = Z_DECIMAL128_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } bson_decimal128_to_string(&intern->decimal, outbuf); PHONGO_RETURN_STRING(outbuf); } /* }}} */ /* {{{ proto array MongoDB\BSON\Decimal128::jsonSerialize() */ static PHP_METHOD(Decimal128, jsonSerialize) { php_phongo_decimal128_t *intern; char outbuf[BSON_DECIMAL128_STRING] = ""; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_DECIMAL128_OBJ_P(getThis()); array_init_size(return_value, 1); bson_decimal128_to_string(&intern->decimal, outbuf); ADD_ASSOC_STRING(return_value, "$numberDecimal", outbuf); } /* }}} */ /* {{{ proto string MongoDB\BSON\Decimal128::serialize() */ static PHP_METHOD(Decimal128, serialize) { php_phongo_decimal128_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval *retval; #endif php_serialize_data_t var_hash; smart_str buf = { 0 }; char outbuf[BSON_DECIMAL128_STRING]; intern = Z_DECIMAL128_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } bson_decimal128_to_string(&intern->decimal, outbuf); #if PHP_VERSION_ID >= 70000 array_init_size(&retval, 1); ADD_ASSOC_STRING(&retval, "dec", outbuf); #else ALLOC_INIT_ZVAL(retval); array_init_size(retval, 1); ADD_ASSOC_STRING(retval, "dec", outbuf); #endif PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC); smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); PHONGO_RETVAL_SMART_STR(buf); smart_str_free(&buf); zval_ptr_dtor(&retval); } /* }}} */ /* {{{ proto void MongoDB\BSON\Decimal128::unserialize(string $serialized) */ static PHP_METHOD(Decimal128, unserialize) { php_phongo_decimal128_t *intern; zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; #if PHP_VERSION_ID >= 70000 zval props; #else zval *props; #endif php_unserialize_data_t var_hash; intern = Z_DECIMAL128_OBJ_P(getThis()); zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); #if PHP_VERSION_ID < 70000 ALLOC_INIT_ZVAL(props); #endif PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&props); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_decimal128_ce->name)); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #if PHP_VERSION_ID >= 70000 php_phongo_decimal128_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC); #else php_phongo_decimal128_init_from_hash(intern, HASH_OF(props) TSRMLS_CC); #endif zval_ptr_dtor(&props); } /* }}} */ /* {{{ MongoDB\BSON\Decimal128 function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128___construct, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_decimal128_me[] = { PHP_ME(Decimal128, __construct, ai_Decimal128___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Decimal128, __set_state, ai_Decimal128___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Decimal128, __toString, ai_Decimal128_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Decimal128, jsonSerialize, ai_Decimal128_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Decimal128, serialize, ai_Decimal128_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Decimal128, unserialize, ai_Decimal128_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\Decimal128 object handlers */ static zend_object_handlers php_phongo_handler_decimal128; static void php_phongo_decimal128_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_decimal128_t *intern = Z_OBJ_DECIMAL128(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->properties) { zend_hash_destroy(intern->properties); FREE_HASHTABLE(intern->properties); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static phongo_create_object_retval php_phongo_decimal128_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_decimal128_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_decimal128_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_decimal128; 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_decimal128_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_decimal128; return retval; } #endif } /* }}} */ static HashTable *php_phongo_decimal128_get_gc(zval *object, phongo_get_gc_table table, int *n TSRMLS_DC) /* {{{ */ { *table = NULL; *n = 0; return Z_DECIMAL128_OBJ_P(object)->properties; } /* }}} */ static HashTable *php_phongo_decimal128_get_properties_hash(zval *object, bool is_debug TSRMLS_DC) /* {{{ */ { php_phongo_decimal128_t *intern; HashTable *props; char outbuf[BSON_DECIMAL128_STRING] = ""; intern = Z_DECIMAL128_OBJ_P(object); PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 1); if (!intern->initialized) { return props; } bson_decimal128_to_string(&intern->decimal, outbuf); #if PHP_VERSION_ID >= 70000 { zval dec; ZVAL_STRING(&dec, outbuf); zend_hash_str_update(props, "dec", sizeof("dec")-1, &dec); } #else { zval *dec; MAKE_STD_ZVAL(dec); ZVAL_STRING(dec, outbuf, 1); zend_hash_update(props, "dec", sizeof("dec"), &dec, sizeof(dec), NULL); } #endif return props; } /* }}} */ static HashTable *php_phongo_decimal128_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { *is_temp = 1; return php_phongo_decimal128_get_properties_hash(object, true TSRMLS_CC); } /* }}} */ static HashTable *php_phongo_decimal128_get_properties(zval *object TSRMLS_DC) /* {{{ */ { return php_phongo_decimal128_get_properties_hash(object, false TSRMLS_CC); } /* }}} */ /* }}} */ void php_phongo_decimal128_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Decimal128", php_phongo_decimal128_me); php_phongo_decimal128_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_decimal128_ce->create_object = php_phongo_decimal128_create_object; PHONGO_CE_FINAL(php_phongo_decimal128_ce); zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_decimal128_interface_ce); zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, zend_ce_serializable); memcpy(&php_phongo_handler_decimal128, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_decimal128.get_debug_info = php_phongo_decimal128_get_debug_info; php_phongo_handler_decimal128.get_gc = php_phongo_decimal128_get_gc; php_phongo_handler_decimal128.get_properties = php_phongo_decimal128_get_properties; #if PHP_VERSION_ID >= 70000 php_phongo_handler_decimal128.free_obj = php_phongo_decimal128_free_object; php_phongo_handler_decimal128.offset = XtOffsetOf(php_phongo_decimal128_t, std); #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.3.4/src/BSON/Decimal128Interface.c0000664000175000017500000000276213210321137020112 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_decimal128_interface_ce; /* {{{ MongoDB\BSON\Decimal128Interface function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_Decimal128Interface_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_decimal128_interface_me[] = { ZEND_ABSTRACT_ME(Decimal128Interface, __toString, ai_Decimal128Interface_void) PHP_FE_END }; /* }}} */ void php_phongo_decimal128_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Decimal128Interface", php_phongo_decimal128_interface_me); php_phongo_decimal128_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/Javascript.c0000664000175000017500000004116613210321137016607 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" zend_class_entry *php_phongo_javascript_ce; /* Initialize the object and return whether it was successful. An exception will * be thrown on error. */ static bool php_phongo_javascript_init(php_phongo_javascript_t *intern, const char *code, phongo_zpp_char_len code_len, zval *scope TSRMLS_DC) /* {{{ */ { if (scope && Z_TYPE_P(scope) != IS_OBJECT && Z_TYPE_P(scope) != IS_ARRAY && Z_TYPE_P(scope) != IS_NULL) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected scope to be array or object, %s given", zend_get_type_by_const(Z_TYPE_P(scope))); return false; } if (strlen(code) != code_len) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Code cannot contain null bytes"); return false; } intern->code = estrndup(code, code_len); intern->code_len = code_len; if (scope && (Z_TYPE_P(scope) == IS_OBJECT || Z_TYPE_P(scope) == IS_ARRAY)) { intern->scope = bson_new(); php_phongo_zval_to_bson(scope, PHONGO_BSON_NONE, intern->scope, NULL TSRMLS_CC); } else { intern->scope = NULL; } return true; } /* }}} */ /* Initialize the object from a HashTable and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_javascript_init_from_hash(php_phongo_javascript_t *intern, HashTable *props TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *code, *scope; if ((code = zend_hash_str_find(props, "code", sizeof("code")-1)) && Z_TYPE_P(code) == IS_STRING) { scope = zend_hash_str_find(props, "scope", sizeof("scope")-1); return php_phongo_javascript_init(intern, Z_STRVAL_P(code), Z_STRLEN_P(code), scope TSRMLS_CC); } #else zval **code, **scope; if (zend_hash_find(props, "code", sizeof("code"), (void**) &code) == SUCCESS && Z_TYPE_PP(code) == IS_STRING) { zval *tmp = zend_hash_find(props, "scope", sizeof("scope"), (void**) &scope) == SUCCESS ? *scope : NULL; return php_phongo_javascript_init(intern, Z_STRVAL_PP(code), Z_STRLEN_PP(code), tmp TSRMLS_CC); } #endif phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"code\" string field", ZSTR_VAL(php_phongo_javascript_ce->name)); return false; } /* }}} */ /* {{{ proto void MongoDB\BSON\Javascript::__construct(string $code[, array|object $scope]) Construct a new BSON Javascript type. The scope is a document mapping identifiers and values, representing the scope in which the code string will be evaluated. Note that this type cannot be represented as Extended JSON. */ static PHP_METHOD(Javascript, __construct) { php_phongo_javascript_t *intern; zend_error_handling error_handling; char *code; phongo_zpp_char_len code_len; zval *scope = NULL; 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!", &code, &code_len, &scope) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); php_phongo_javascript_init(intern, code, code_len, scope TSRMLS_CC); } /* }}} */ /* {{{ proto void MongoDB\BSON\Javascript::__set_state(array $properties) */ static PHP_METHOD(Javascript, __set_state) { php_phongo_javascript_t *intern; HashTable *props; zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_javascript_ce); intern = Z_JAVASCRIPT_OBJ_P(return_value); props = Z_ARRVAL_P(array); php_phongo_javascript_init_from_hash(intern, props TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\Javascript::__toString() Return the Javascript's code string. */ static PHP_METHOD(Javascript, __toString) { php_phongo_javascript_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_JAVASCRIPT_OBJ_P(getThis()); PHONGO_RETURN_STRINGL(intern->code, intern->code_len); } /* }}} */ /* {{{ proto string MongoDB\BSON\Javascript::getCode() */ static PHP_METHOD(Javascript, getCode) { php_phongo_javascript_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_JAVASCRIPT_OBJ_P(getThis()); PHONGO_RETURN_STRINGL(intern->code, intern->code_len); } /* }}} */ /* {{{ proto object|null MongoDB\BSON\Javascript::getScope() */ static PHP_METHOD(Javascript, getScope) { php_phongo_javascript_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_JAVASCRIPT_OBJ_P(getThis()); if (!intern->scope) { RETURN_NULL(); } if (intern->scope->len) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state); #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } else { RETURN_NULL(); } } /* }}} */ /* {{{ proto array MongoDB\BSON\Javascript::jsonSerialize() */ static PHP_METHOD(Javascript, jsonSerialize) { php_phongo_javascript_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_JAVASCRIPT_OBJ_P(getThis()); array_init_size(return_value, 2); ADD_ASSOC_STRINGL(return_value, "$code", intern->code, intern->code_len); if (intern->scope && intern->scope->len) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; if (php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) { #if PHP_VERSION_ID >= 70000 Z_ADDREF(state.zchild); ADD_ASSOC_ZVAL_EX(return_value, "$scope", &state.zchild); #else Z_ADDREF_P(state.zchild); ADD_ASSOC_ZVAL_EX(return_value, "$scope", state.zchild); #endif } zval_ptr_dtor(&state.zchild); } } /* }}} */ /* {{{ proto string MongoDB\BSON\Javascript::serialize() */ static PHP_METHOD(Javascript, serialize) { php_phongo_javascript_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval *retval; #endif php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; php_serialize_data_t var_hash; smart_str buf = { 0 }; intern = Z_JAVASCRIPT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } #if PHP_VERSION_ID >= 70000 if (intern->scope && intern->scope->len) { if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) { return; } Z_ADDREF(state.zchild); } else { ZVAL_NULL(&state.zchild); } #else if (intern->scope && intern->scope->len) { if (!php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) { return; } Z_ADDREF_P(state.zchild); } else { MAKE_STD_ZVAL(state.zchild); ZVAL_NULL(state.zchild); Z_ADDREF_P(state.zchild); } #endif #if PHP_VERSION_ID >= 70000 array_init_size(&retval, 2); ADD_ASSOC_STRINGL(&retval, "code", intern->code, intern->code_len); ADD_ASSOC_ZVAL(&retval, "scope", &state.zchild); #else ALLOC_INIT_ZVAL(retval); array_init_size(retval, 2); ADD_ASSOC_STRINGL(retval, "code", intern->code, intern->code_len); ADD_ASSOC_ZVAL(retval, "scope", state.zchild); #endif PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC); smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); PHONGO_RETVAL_SMART_STR(buf); smart_str_free(&buf); zval_ptr_dtor(&retval); zval_ptr_dtor(&state.zchild); } /* }}} */ /* {{{ proto void MongoDB\BSON\Javascript::unserialize(string $serialized) */ static PHP_METHOD(Javascript, unserialize) { php_phongo_javascript_t *intern; zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; #if PHP_VERSION_ID >= 70000 zval props; #else zval *props; #endif php_unserialize_data_t var_hash; intern = Z_JAVASCRIPT_OBJ_P(getThis()); zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); #if PHP_VERSION_ID < 70000 ALLOC_INIT_ZVAL(props); #endif PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&props); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_javascript_ce->name)); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #if PHP_VERSION_ID >= 70000 php_phongo_javascript_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC); #else php_phongo_javascript_init_from_hash(intern, HASH_OF(props) TSRMLS_CC); #endif zval_ptr_dtor(&props); } /* }}} */ /* {{{ MongoDB\BSON\Javascript function entries */ 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() ZEND_BEGIN_ARG_INFO_EX(ai_Javascript___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Javascript_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Javascript_void, 0, 0, 0) 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(Javascript, __set_state, ai_Javascript___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Javascript, __toString, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Javascript, jsonSerialize, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Javascript, serialize, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Javascript, unserialize, ai_Javascript_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Javascript, getCode, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Javascript, getScope, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\Javascript object handlers */ static zend_object_handlers php_phongo_handler_javascript; 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->code) { efree(intern->code); } if (intern->scope) { bson_destroy(intern->scope); intern->scope = NULL; } if (intern->properties) { zend_hash_destroy(intern->properties); FREE_HASHTABLE(intern->properties); } #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); #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 } /* }}} */ static int php_phongo_javascript_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_javascript_t *intern1, *intern2; intern1 = Z_JAVASCRIPT_OBJ_P(o1); intern2 = Z_JAVASCRIPT_OBJ_P(o2); /* Do not consider the scope document for comparisons */ return strcmp(intern1->code, intern2->code); } /* }}} */ static HashTable *php_phongo_javascript_get_gc(zval *object, phongo_get_gc_table table, int *n TSRMLS_DC) /* {{{ */ { *table = NULL; *n = 0; return Z_JAVASCRIPT_OBJ_P(object)->properties; } /* }}} */ HashTable *php_phongo_javascript_get_properties_hash(zval *object, bool is_debug TSRMLS_DC) /* {{{ */ { php_phongo_javascript_t *intern; HashTable *props; intern = Z_JAVASCRIPT_OBJ_P(object); PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2); if (!intern->code) { return props; } #if PHP_VERSION_ID >= 70000 { zval code; ZVAL_STRING(&code, intern->code); zend_hash_str_update(props, "code", sizeof("code")-1, &code); if (intern->scope) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; if (php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) { Z_ADDREF(state.zchild); zend_hash_str_update(props, "scope", sizeof("scope")-1, &state.zchild); } else { zval scope; ZVAL_NULL(&scope); zend_hash_str_update(props, "scope", sizeof("scope")-1, &scope); } zval_ptr_dtor(&state.zchild); } else { zval scope; ZVAL_NULL(&scope); zend_hash_str_update(props, "scope", sizeof("scope")-1, &scope); } } #else { zval *code; MAKE_STD_ZVAL(code); ZVAL_STRING(code, intern->code, 1); zend_hash_update(props, "code", sizeof("code"), &code, sizeof(code), NULL); if (intern->scope) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; if (php_phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) { Z_ADDREF_P(state.zchild); zend_hash_update(props, "scope", sizeof("scope"), &state.zchild, sizeof(state.zchild), NULL); } else { zval *scope; MAKE_STD_ZVAL(scope); ZVAL_NULL(scope); zend_hash_update(props, "scope", sizeof("scope"), &scope, sizeof(scope), NULL); } zval_ptr_dtor(&state.zchild); } else { zval *scope; MAKE_STD_ZVAL(scope); ZVAL_NULL(scope); zend_hash_update(props, "scope", sizeof("scope"), &scope, sizeof(scope), NULL); } } #endif return props; } /* }}} */ static HashTable *php_phongo_javascript_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { *is_temp = 1; return php_phongo_javascript_get_properties_hash(object, true TSRMLS_CC); } /* }}} */ static HashTable *php_phongo_javascript_get_properties(zval *object TSRMLS_DC) /* {{{ */ { return php_phongo_javascript_get_properties_hash(object, false TSRMLS_CC); } /* }}} */ /* }}} */ void php_phongo_javascript_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_javascript_ce); zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_javascript_interface_ce); zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, zend_ce_serializable); memcpy(&php_phongo_handler_javascript, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_javascript.compare_objects = php_phongo_javascript_compare_objects; php_phongo_handler_javascript.get_debug_info = php_phongo_javascript_get_debug_info; php_phongo_handler_javascript.get_gc = php_phongo_javascript_get_gc; php_phongo_handler_javascript.get_properties = php_phongo_javascript_get_properties; #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 } /* }}} */ /* * 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.3.4/src/BSON/JavascriptInterface.c0000664000175000017500000000321513210321137020421 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_javascript_interface_ce; /* {{{ MongoDB\BSON\JavascriptInterface function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_JavascriptInterface_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_javascript_interface_me[] = { ZEND_ABSTRACT_ME(JavascriptInterface, getCode, ai_JavascriptInterface_void) ZEND_ABSTRACT_ME(JavascriptInterface, getScope, ai_JavascriptInterface_void) ZEND_ABSTRACT_ME(JavascriptInterface, __toString, ai_JavascriptInterface_void) PHP_FE_END }; /* }}} */ void php_phongo_javascript_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "JavascriptInterface", php_phongo_javascript_interface_me); php_phongo_javascript_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/MaxKey.c0000664000175000017500000001210413210321137015665 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_maxkey_ce; /* {{{ proto void MongoDB\BSON\MaxKey::__set_state(array $properties) */ static PHP_METHOD(MaxKey, __set_state) { zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_maxkey_ce); } /* }}} */ /* {{{ proto array MongoDB\BSON\MaxKey::jsonSerialize() */ static PHP_METHOD(MaxKey, jsonSerialize) { if (zend_parse_parameters_none() == FAILURE) { return; } array_init_size(return_value, 1); ADD_ASSOC_LONG_EX(return_value, "$maxKey", 1); } /* }}} */ /* {{{ proto string MongoDB\BSON\MaxKey::serialize() */ static PHP_METHOD(MaxKey, serialize) { PHONGO_RETURN_STRING(""); } /* }}} */ /* {{{ proto void MongoDB\BSON\MaxKey::unserialize(string $serialized) */ static PHP_METHOD(MaxKey, unserialize) { zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); } /* }}} */ /* {{{ MongoDB\BSON\MaxKey function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_MaxKey___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_MaxKey_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_MaxKey_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_maxkey_me[] = { PHP_ME(MaxKey, __set_state, ai_MaxKey___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(MaxKey, jsonSerialize, ai_MaxKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(MaxKey, serialize, ai_MaxKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(MaxKey, unserialize, ai_MaxKey_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\MaxKey object handlers */ static zend_object_handlers php_phongo_handler_maxkey; 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 } /* }}} */ static 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 } /* }}} */ /* }}} */ void php_phongo_maxkey_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_maxkey_ce); zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_maxkey_interface_ce); zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, zend_ce_serializable); 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 } /* }}} */ /* * 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.3.4/src/BSON/MaxKeyInterface.c0000664000175000017500000000246413210321137017516 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_maxkey_interface_ce; /* {{{ MongoDB\BSON\MaxKeyInterface function entries */ static zend_function_entry php_phongo_maxkey_interface_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_maxkey_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "MaxKeyInterface", php_phongo_maxkey_interface_me); php_phongo_maxkey_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/MinKey.c0000664000175000017500000001210513210321137015664 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_minkey_ce; /* {{{ proto void MongoDB\BSON\MinKey::__set_state(array $properties) */ static PHP_METHOD(MinKey, __set_state) { zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_minkey_ce); } /* }}} */ /* {{{ proto array MongoDB\BSON\MinKey::jsonSerialize() */ static PHP_METHOD(MinKey, jsonSerialize) { if (zend_parse_parameters_none() == FAILURE) { return; } array_init_size(return_value, 1); ADD_ASSOC_LONG_EX(return_value, "$minKey", 1); } /* }}} */ /* {{{ proto string MongoDB\BSON\MinKey::serialize() */ static PHP_METHOD(MinKey, serialize) { PHONGO_RETURN_STRING(""); } /* }}} */ /* {{{ proto void MongoDB\BSON\MinKey::unserialize(string $serialized) */ static PHP_METHOD(MinKey, unserialize) { zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); } /* }}} */ /* {{{ MongoDB\BSON\MinKey function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_MinKey___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_MinKey_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_MinKey_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_minkey_me[] = { PHP_ME(MinKey, __set_state, ai_MinKey___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(MinKey, jsonSerialize, ai_MinKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(MinKey, serialize, ai_MinKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(MinKey, unserialize, ai_MinKey_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\MinKey object handlers */ static zend_object_handlers php_phongo_handler_minkey; 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 } /* }}} */ static 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 } /* }}} */ /* }}} */ void php_phongo_minkey_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_minkey_ce); zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_minkey_interface_ce); zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, zend_ce_serializable); 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 } /* }}} */ /* * 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.3.4/src/BSON/MinKeyInterface.c0000664000175000017500000000246413210321137017514 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_minkey_interface_ce; /* {{{ MongoDB\BSON\MinKeyInterface function entries */ static zend_function_entry php_phongo_minkey_interface_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_minkey_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "MinKeyInterface", php_phongo_minkey_interface_me); php_phongo_minkey_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/ObjectId.c0000664000175000017500000003123013210321137016153 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_objectid_ce; /* Initialize the object with a generated value and return whether it was * successful. */ static bool php_phongo_objectid_init(php_phongo_objectid_t *intern) { bson_oid_t oid; intern->initialized = true; bson_oid_init(&oid, NULL); bson_oid_to_string(&oid, intern->oid); return true; } /* Initialize the object from a hex string and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_objectid_init_from_hex_string(php_phongo_objectid_t *intern, const char *hex, phongo_zpp_char_len hex_len TSRMLS_DC) /* {{{ */ { if (bson_oid_is_valid(hex, hex_len)) { bson_oid_t oid; bson_oid_init_from_string(&oid, hex); bson_oid_to_string(&oid, intern->oid); intern->initialized = true; return true; } phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing ObjectId string: %s", hex); return false; } /* }}} */ /* Initialize the object from a HashTable and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_objectid_init_from_hash(php_phongo_objectid_t *intern, HashTable *props TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *z_oid; z_oid = zend_hash_str_find(props, "oid", sizeof("oid")-1); if (z_oid && Z_TYPE_P(z_oid) == IS_STRING) { return php_phongo_objectid_init_from_hex_string(intern, Z_STRVAL_P(z_oid), Z_STRLEN_P(z_oid) TSRMLS_CC); } #else zval **z_oid; if (zend_hash_find(props, "oid", sizeof("oid"), (void**) &z_oid) == SUCCESS && Z_TYPE_PP(z_oid) == IS_STRING) { return php_phongo_objectid_init_from_hex_string(intern, Z_STRVAL_PP(z_oid), Z_STRLEN_PP(z_oid) TSRMLS_CC); } #endif phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"oid\" string field", ZSTR_VAL(php_phongo_objectid_ce->name)); return false; } /* }}} */ /* {{{ proto void MongoDB\BSON\ObjectId::__construct([string $id]) Constructs a new BSON ObjectId type, optionally from a hex string. */ static 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) { php_phongo_objectid_init_from_hex_string(intern, id, id_len TSRMLS_CC); } else { php_phongo_objectid_init(intern); } } /* }}} */ /* {{{ proto integer MongoDB\BSON\ObjectId::getTimestamp() */ static PHP_METHOD(ObjectId, getTimestamp) { php_phongo_objectid_t *intern; bson_oid_t tmp_oid; intern = Z_OBJECTID_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } bson_oid_init_from_string(&tmp_oid, intern->oid); RETVAL_LONG(bson_oid_get_time_t(&tmp_oid)); } /* }}} */ /* {{{ proto MongoDB\BSON\ObjectId::__set_state(array $properties) */ static PHP_METHOD(ObjectId, __set_state) { php_phongo_objectid_t *intern; HashTable *props; zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_objectid_ce); intern = Z_OBJECTID_OBJ_P(return_value); props = Z_ARRVAL_P(array); php_phongo_objectid_init_from_hash(intern, props TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\ObjectId::__toString() */ static 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); } /* }}} */ /* {{{ proto array MongoDB\BSON\ObjectId::jsonSerialize() */ static PHP_METHOD(ObjectId, jsonSerialize) { php_phongo_objectid_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_OBJECTID_OBJ_P(getThis()); array_init_size(return_value, 1); ADD_ASSOC_STRINGL(return_value, "$oid", intern->oid, 24); } /* }}} */ /* {{{ proto string MongoDB\BSON\ObjectId::serialize() */ static PHP_METHOD(ObjectId, serialize) { php_phongo_objectid_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval *retval; #endif php_serialize_data_t var_hash; smart_str buf = { 0 }; intern = Z_OBJECTID_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } #if PHP_VERSION_ID >= 70000 array_init_size(&retval, 2); ADD_ASSOC_STRINGL(&retval, "oid", intern->oid, 24); #else ALLOC_INIT_ZVAL(retval); array_init_size(retval, 2); ADD_ASSOC_STRINGL(retval, "oid", intern->oid, 24); #endif PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC); smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); PHONGO_RETVAL_SMART_STR(buf); smart_str_free(&buf); zval_ptr_dtor(&retval); } /* }}} */ /* {{{ proto void MongoDB\BSON\ObjectId::unserialize(string $serialized) */ static PHP_METHOD(ObjectId, unserialize) { php_phongo_objectid_t *intern; zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; #if PHP_VERSION_ID >= 70000 zval props; #else zval *props; #endif php_unserialize_data_t var_hash; intern = Z_OBJECTID_OBJ_P(getThis()); zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); #if PHP_VERSION_ID < 70000 ALLOC_INIT_ZVAL(props); #endif PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&props); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_objectid_ce->name)); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #if PHP_VERSION_ID >= 70000 php_phongo_objectid_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC); #else php_phongo_objectid_init_from_hash(intern, HASH_OF(props) TSRMLS_CC); #endif zval_ptr_dtor(&props); } /* }}} */ /* {{{ MongoDB\BSON\ObjectId function entries */ 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___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_ObjectId_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_ObjectId_void, 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, getTimestamp, ai_ObjectId_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ObjectId, __set_state, ai_ObjectId___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(ObjectId, __toString, ai_ObjectId_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ObjectId, jsonSerialize, ai_ObjectId_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ObjectId, serialize, ai_ObjectId_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ObjectId, unserialize, ai_ObjectId_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\ObjectId object handlers */ static zend_object_handlers php_phongo_handler_objectid; 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 (intern->properties) { zend_hash_destroy(intern->properties); FREE_HASHTABLE(intern->properties); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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); } /* }}} */ static HashTable *php_phongo_objectid_get_gc(zval *object, phongo_get_gc_table table, int *n TSRMLS_DC) /* {{{ */ { *table = NULL; *n = 0; return Z_OBJECTID_OBJ_P(object)->properties; } /* }}} */ static HashTable *php_phongo_objectid_get_properties_hash(zval *object, bool is_debug TSRMLS_DC) /* {{{ */ { php_phongo_objectid_t *intern; HashTable *props; intern = Z_OBJECTID_OBJ_P(object); PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 1); if (!intern->oid) { return props; } #if PHP_VERSION_ID >= 70000 { zval zv; ZVAL_STRING(&zv, intern->oid); zend_hash_str_update(props, "oid", sizeof("oid")-1, &zv); } #else { zval *zv; MAKE_STD_ZVAL(zv); ZVAL_STRING(zv, intern->oid, 1); zend_hash_update(props, "oid", sizeof("oid"), &zv, sizeof(zv), NULL); } #endif return props; } /* }}} */ static HashTable *php_phongo_objectid_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { *is_temp = 1; return php_phongo_objectid_get_properties_hash(object, true TSRMLS_CC); } /* }}} */ static HashTable *php_phongo_objectid_get_properties(zval *object TSRMLS_DC) /* {{{ */ { return php_phongo_objectid_get_properties_hash(object, false TSRMLS_CC); } /* }}} */ /* }}} */ void php_phongo_objectid_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_objectid_ce); zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_objectid_interface_ce); zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, zend_ce_serializable); 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; php_phongo_handler_objectid.get_gc = php_phongo_objectid_get_gc; php_phongo_handler_objectid.get_properties = php_phongo_objectid_get_properties; #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 } /* }}} */ /* * 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.3.4/src/BSON/ObjectIdInterface.c0000664000175000017500000000305413210321137017777 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_objectid_interface_ce; /* {{{ MongoDB\BSON\ObjectIdInterface function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_ObjectIdInterface_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_objectid_interface_me[] = { ZEND_ABSTRACT_ME(ObjectIdInterface, getTimestamp, ai_ObjectIdInterface_void) ZEND_ABSTRACT_ME(ObjectIdInterface, __toString, ai_ObjectIdInterface_void) PHP_FE_END }; /* }}} */ void php_phongo_objectid_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "ObjectIdInterface", php_phongo_objectid_interface_me); php_phongo_objectid_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/Persistable.c0000664000175000017500000000262113210321137016747 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_persistable_ce; /* {{{ MongoDB\BSON\Persistable function entries */ static zend_function_entry php_phongo_persistable_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_persistable_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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); } /* }}} */ /* * 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.3.4/src/BSON/Regex.c0000664000175000017500000003520313210321137015546 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_regex_ce; /* qsort() compare callback for alphabetizing regex flags upon initialization */ static int php_phongo_regex_compare_flags(const void *f1, const void *f2) /* {{{ */ { if (* (const char *) f1 == * (const char *) f2) { return 0; } return (* (const char *) f1 > * (const char *) f2) ? 1 : -1; } /* }}} */ /* Initialize the object and return whether it was successful. An exception will * be thrown on error. */ static bool php_phongo_regex_init(php_phongo_regex_t *intern, const char *pattern, phongo_zpp_char_len pattern_len, const char *flags, phongo_zpp_char_len flags_len TSRMLS_DC) /* {{{ */ { if (strlen(pattern) != pattern_len) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Pattern cannot contain null bytes"); return false; } intern->pattern = estrndup(pattern, pattern_len); intern->pattern_len = pattern_len; if (flags) { if (strlen(flags) != flags_len) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Flags cannot contain null bytes"); return false; } intern->flags = estrndup(flags, flags_len); intern->flags_len = flags_len; /* Ensure flags are alphabetized upon initialization */ qsort((void *) intern->flags, flags_len, 1, php_phongo_regex_compare_flags); } else { intern->flags = estrdup(""); intern->flags_len = 0; } return true; } /* }}} */ /* Initialize the object from a HashTable and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_regex_init_from_hash(php_phongo_regex_t *intern, HashTable *props TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *pattern, *flags; if ((pattern = zend_hash_str_find(props, "pattern", sizeof("pattern")-1)) && Z_TYPE_P(pattern) == IS_STRING && (flags = zend_hash_str_find(props, "flags", sizeof("flags")-1)) && Z_TYPE_P(flags) == IS_STRING) { return php_phongo_regex_init(intern, Z_STRVAL_P(pattern), Z_STRLEN_P(pattern), Z_STRVAL_P(flags), Z_STRLEN_P(flags) TSRMLS_CC); } #else zval **pattern, **flags; if (zend_hash_find(props, "pattern", sizeof("pattern"), (void**) &pattern) == SUCCESS && Z_TYPE_PP(pattern) == IS_STRING && zend_hash_find(props, "flags", sizeof("flags"), (void**) &flags) == SUCCESS && Z_TYPE_PP(flags) == IS_STRING) { return php_phongo_regex_init(intern, Z_STRVAL_PP(pattern), Z_STRLEN_PP(pattern), Z_STRVAL_PP(flags), Z_STRLEN_PP(flags) TSRMLS_CC); } #endif phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"pattern\" and \"flags\" string fields", ZSTR_VAL(php_phongo_regex_ce->name)); return false; } /* }}} */ /* {{{ proto void MongoDB\BSON\Regex::__construct(string $pattern [, string $flags]) Constructs a new BSON regular expression type. */ static PHP_METHOD(Regex, __construct) { php_phongo_regex_t *intern; zend_error_handling error_handling; char *pattern; phongo_zpp_char_len pattern_len; char *flags = NULL; phongo_zpp_char_len flags_len = 0; 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, "s|s", &pattern, &pattern_len, &flags, &flags_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); php_phongo_regex_init(intern, pattern, pattern_len, flags, flags_len TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\Regex::getPattern() */ static 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 string MongoDB\BSON\Regex::getFlags() */ static 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 MongoDB\BSON\Regex::__set_state(array $properties) */ static PHP_METHOD(Regex, __set_state) { php_phongo_regex_t *intern; HashTable *props; zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_regex_ce); intern = Z_REGEX_OBJ_P(return_value); props = Z_ARRVAL_P(array); php_phongo_regex_init_from_hash(intern, props TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\Regex::__toString() Returns a string in the form: /pattern/flags */ static 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); } /* }}} */ /* {{{ proto array MongoDB\BSON\Regex::jsonSerialize() */ static PHP_METHOD(Regex, jsonSerialize) { php_phongo_regex_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_REGEX_OBJ_P(getThis()); array_init_size(return_value, 2); ADD_ASSOC_STRINGL(return_value, "$regex", intern->pattern, intern->pattern_len); ADD_ASSOC_STRINGL(return_value, "$options", intern->flags, intern->flags_len); } /* }}} */ /* {{{ proto string MongoDB\BSON\Regex::serialize() */ static PHP_METHOD(Regex, serialize) { php_phongo_regex_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval *retval; #endif php_serialize_data_t var_hash; smart_str buf = { 0 }; intern = Z_REGEX_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } #if PHP_VERSION_ID >= 70000 array_init_size(&retval, 2); ADD_ASSOC_STRINGL(&retval, "pattern", intern->pattern, intern->pattern_len); ADD_ASSOC_STRINGL(&retval, "flags", intern->flags, intern->flags_len); #else ALLOC_INIT_ZVAL(retval); array_init_size(retval, 2); ADD_ASSOC_STRINGL(retval, "pattern", intern->pattern, intern->pattern_len); ADD_ASSOC_STRINGL(retval, "flags", intern->flags, intern->flags_len); #endif PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC); smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); PHONGO_RETVAL_SMART_STR(buf); smart_str_free(&buf); zval_ptr_dtor(&retval); } /* }}} */ /* {{{ proto void MongoDB\BSON\Regex::unserialize(string $serialized) */ static PHP_METHOD(Regex, unserialize) { php_phongo_regex_t *intern; zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; #if PHP_VERSION_ID >= 70000 zval props; #else zval *props; #endif php_unserialize_data_t var_hash; intern = Z_REGEX_OBJ_P(getThis()); zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); #if PHP_VERSION_ID < 70000 ALLOC_INIT_ZVAL(props); #endif PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&props); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_regex_ce->name)); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #if PHP_VERSION_ID >= 70000 php_phongo_regex_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC); #else php_phongo_regex_init_from_hash(intern, HASH_OF(props) TSRMLS_CC); #endif zval_ptr_dtor(&props); } /* }}} */ /* {{{ MongoDB\BSON\Regex function entries */ 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___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Regex_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Regex_void, 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, __set_state, ai_Regex___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Regex, __toString, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, jsonSerialize, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, serialize, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, unserialize, ai_Regex_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, getPattern, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, getFlags, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\Regex object handlers */ static zend_object_handlers php_phongo_handler_regex; 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 (intern->properties) { zend_hash_destroy(intern->properties); FREE_HASHTABLE(intern->properties); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static int php_phongo_regex_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_regex_t *intern1, *intern2; int retval; intern1 = Z_REGEX_OBJ_P(o1); intern2 = Z_REGEX_OBJ_P(o2); /* MongoDB compares the pattern string before the flags. */ retval = strcmp(intern1->pattern, intern2->pattern); if (retval != 0) { return retval; } return strcmp(intern1->flags, intern2->flags); } /* }}} */ static HashTable *php_phongo_regex_get_gc(zval *object, phongo_get_gc_table table, int *n TSRMLS_DC) /* {{{ */ { *table = NULL; *n = 0; return Z_REGEX_OBJ_P(object)->properties; } /* }}} */ static HashTable *php_phongo_regex_get_properties_hash(zval *object, bool is_debug TSRMLS_DC) /* {{{ */ { php_phongo_regex_t *intern; HashTable *props; intern = Z_REGEX_OBJ_P(object); PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2); if (!intern->pattern) { return props; } #if PHP_VERSION_ID >= 70000 { zval pattern, flags; ZVAL_STRINGL(&pattern, intern->pattern, intern->pattern_len); zend_hash_str_update(props, "pattern", sizeof("pattern")-1, &pattern); ZVAL_STRINGL(&flags, intern->flags, intern->flags_len); zend_hash_str_update(props, "flags", sizeof("flags")-1, &flags); } #else { zval *pattern, *flags; MAKE_STD_ZVAL(pattern); ZVAL_STRINGL(pattern, intern->pattern, intern->pattern_len, 1); zend_hash_update(props, "pattern", sizeof("pattern"), &pattern, sizeof(pattern), NULL); MAKE_STD_ZVAL(flags); ZVAL_STRINGL(flags, intern->flags, intern->flags_len, 1); zend_hash_update(props, "flags", sizeof("flags"), &flags, sizeof(flags), NULL); } #endif return props; } /* }}} */ static HashTable *php_phongo_regex_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { *is_temp = 1; return php_phongo_regex_get_properties_hash(object, true TSRMLS_CC); } /* }}} */ static HashTable *php_phongo_regex_get_properties(zval *object TSRMLS_DC) /* {{{ */ { return php_phongo_regex_get_properties_hash(object, false TSRMLS_CC); } /* }}} */ /* }}} */ void php_phongo_regex_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_regex_ce); zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_regex_interface_ce); zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, zend_ce_serializable); zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); memcpy(&php_phongo_handler_regex, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_regex.compare_objects = php_phongo_regex_compare_objects; php_phongo_handler_regex.get_debug_info = php_phongo_regex_get_debug_info; php_phongo_handler_regex.get_gc = php_phongo_regex_get_gc; php_phongo_handler_regex.get_properties = php_phongo_regex_get_properties; #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 } /* }}} */ /* * 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.3.4/src/BSON/RegexInterface.c0000664000175000017500000000311213210321137017361 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_regex_interface_ce; /* {{{ MongoDB\BSON\RegexInterface function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_RegexInterface_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_regex_interface_me[] = { ZEND_ABSTRACT_ME(RegexInterface, getFlags, ai_RegexInterface_void) ZEND_ABSTRACT_ME(RegexInterface, getPattern, ai_RegexInterface_void) ZEND_ABSTRACT_ME(RegexInterface, __toString, ai_RegexInterface_void) PHP_FE_END }; /* }}} */ void php_phongo_regex_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "RegexInterface", php_phongo_regex_interface_me); php_phongo_regex_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/Serializable.c0000664000175000017500000000300313210321137017073 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_serializable_ce; /* {{{ MongoDB\BSON\Serializable function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_Serializable_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_serializable_me[] = { ZEND_ABSTRACT_ME(Serializable, bsonSerialize, ai_Serializable_void) PHP_FE_END }; /* }}} */ void php_phongo_serializable_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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); } /* }}} */ /* * 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.3.4/src/BSON/Timestamp.c0000664000175000017500000004537513210321137016452 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_timestamp_ce; /* Initialize the object and return whether it was successful. An exception will * be thrown on error. */ static bool php_phongo_timestamp_init(php_phongo_timestamp_t *intern, int64_t increment, int64_t timestamp TSRMLS_DC) /* {{{ */ { 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 false; } 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 false; } intern->increment = (uint32_t) increment; intern->timestamp = (uint32_t) timestamp; intern->initialized = true; return true; } /* }}} */ /* Initialize the object from numeric strings and return whether it was * successful. An exception will be thrown on error. */ static bool php_phongo_timestamp_init_from_string(php_phongo_timestamp_t *intern, const char *s_increment, phongo_zpp_char_len s_increment_len, const char *s_timestamp, phongo_zpp_char_len s_timestamp_len TSRMLS_DC) /* {{{ */ { int64_t increment, timestamp; char *endptr = NULL; errno = 0; /* errno will set errno if conversion fails; however, we do not need to * specify the type of error. * * Note: bson_ascii_strtoll() does not properly detect out-of-range values * (see: CDRIVER-1377). strtoll() would be preferable, but it is not * available on all platforms (e.g. HP-UX), and atoll() provides no error * reporting at all. */ increment = bson_ascii_strtoll(s_increment, &endptr, 10); if (errno || (endptr && endptr != ((const char *)s_increment + s_increment_len))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit integer increment for %s initialization", s_increment, ZSTR_VAL(php_phongo_timestamp_ce->name)); return false; } timestamp = bson_ascii_strtoll(s_timestamp, &endptr, 10); if (errno || (endptr && endptr != ((const char *)s_timestamp + s_timestamp_len))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit integer timestamp for %s initialization", s_timestamp, ZSTR_VAL(php_phongo_timestamp_ce->name)); return false; } return php_phongo_timestamp_init(intern, increment, timestamp TSRMLS_CC); } /* }}} */ /* Initialize the object from a HashTable and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_timestamp_init_from_hash(php_phongo_timestamp_t *intern, HashTable *props TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *increment, *timestamp; if ((increment = zend_hash_str_find(props, "increment", sizeof("increment")-1)) && Z_TYPE_P(increment) == IS_LONG && (timestamp = zend_hash_str_find(props, "timestamp", sizeof("timestamp")-1)) && Z_TYPE_P(timestamp) == IS_LONG) { return php_phongo_timestamp_init(intern, Z_LVAL_P(increment), Z_LVAL_P(timestamp) TSRMLS_CC); } if ((increment = zend_hash_str_find(props, "increment", sizeof("increment")-1)) && Z_TYPE_P(increment) == IS_STRING && (timestamp = zend_hash_str_find(props, "timestamp", sizeof("timestamp")-1)) && Z_TYPE_P(timestamp) == IS_STRING) { return php_phongo_timestamp_init_from_string(intern, Z_STRVAL_P(increment), Z_STRLEN_P(increment), Z_STRVAL_P(timestamp), Z_STRLEN_P(timestamp) TSRMLS_CC); } #else zval **increment, **timestamp; if (zend_hash_find(props, "increment", sizeof("increment"), (void**) &increment) == SUCCESS && Z_TYPE_PP(increment) == IS_LONG && zend_hash_find(props, "timestamp", sizeof("timestamp"), (void**) ×tamp) == SUCCESS && Z_TYPE_PP(timestamp) == IS_LONG) { return php_phongo_timestamp_init(intern, Z_LVAL_PP(increment), Z_LVAL_PP(timestamp) TSRMLS_CC); } if (zend_hash_find(props, "increment", sizeof("increment"), (void**) &increment) == SUCCESS && Z_TYPE_PP(increment) == IS_STRING && zend_hash_find(props, "timestamp", sizeof("timestamp"), (void**) ×tamp) == SUCCESS && Z_TYPE_PP(timestamp) == IS_STRING) { return php_phongo_timestamp_init_from_string(intern, Z_STRVAL_PP(increment), Z_STRLEN_PP(increment), Z_STRVAL_PP(timestamp), Z_STRLEN_PP(timestamp) TSRMLS_CC); } #endif phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"increment\" and \"timestamp\" integer or numeric string fields", ZSTR_VAL(php_phongo_timestamp_ce->name)); return false; } /* }}} */ /* {{{ proto void MongoDB\BSON\Timestamp::__construct(int|string $increment, int|string $timestamp) Construct a new BSON timestamp type, which consists of a 4-byte increment and 4-byte timestamp. */ static PHP_METHOD(Timestamp, __construct) { php_phongo_timestamp_t *intern; zend_error_handling error_handling; zval *increment = NULL, *timestamp = NULL; 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, "zz", &increment, ×tamp) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (Z_TYPE_P(increment) == IS_LONG && Z_TYPE_P(timestamp) == IS_LONG) { php_phongo_timestamp_init(intern, Z_LVAL_P(increment), Z_LVAL_P(timestamp) TSRMLS_CC); return; } if (Z_TYPE_P(increment) == IS_LONG) { convert_to_string(increment); } if (Z_TYPE_P(increment) != IS_STRING) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected increment to be an unsigned 32-bit integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(increment))); return; } if (Z_TYPE_P(timestamp) == IS_LONG) { convert_to_string(timestamp); } if (Z_TYPE_P(timestamp) != IS_STRING) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected timestamp to be an unsigned 32-bit integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(timestamp))); return; } php_phongo_timestamp_init_from_string(intern, Z_STRVAL_P(increment), Z_STRLEN_P(increment), Z_STRVAL_P(timestamp), Z_STRLEN_P(timestamp) TSRMLS_CC); } /* }}} */ /* {{{ proto integer MongoDB\BSON\Timestamp::getIncrement() */ static PHP_METHOD(Timestamp, getIncrement) { php_phongo_timestamp_t *intern; intern = Z_TIMESTAMP_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETVAL_LONG(intern->increment); } /* }}} */ /* {{{ proto integer MongoDB\BSON\Timestamp::getTimestamp() */ static PHP_METHOD(Timestamp, getTimestamp) { php_phongo_timestamp_t *intern; intern = Z_TIMESTAMP_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETVAL_LONG(intern->timestamp); } /* }}} */ /* {{{ proto void MongoDB\BSON\Timestamp::__set_state(array $properties) */ static PHP_METHOD(Timestamp, __set_state) { php_phongo_timestamp_t *intern; HashTable *props; zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_timestamp_ce); intern = Z_TIMESTAMP_OBJ_P(return_value); props = Z_ARRVAL_P(array); php_phongo_timestamp_init_from_hash(intern, props TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\Timestamp::__toString() Returns a string in the form: [increment:timestamp] */ static 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); } /* }}} */ /* {{{ proto array MongoDB\BSON\Timestamp::jsonSerialize() */ static PHP_METHOD(Timestamp, jsonSerialize) { php_phongo_timestamp_t *intern; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_TIMESTAMP_OBJ_P(getThis()); array_init_size(return_value, 1); #if PHP_VERSION_ID >= 70000 { zval ts; array_init_size(&ts, 2); ADD_ASSOC_LONG_EX(&ts, "t", intern->timestamp); ADD_ASSOC_LONG_EX(&ts, "i", intern->increment); ADD_ASSOC_ZVAL_EX(return_value, "$timestamp", &ts); } #else { zval *ts; MAKE_STD_ZVAL(ts); array_init_size(ts, 2); ADD_ASSOC_LONG_EX(ts, "t", intern->timestamp); ADD_ASSOC_LONG_EX(ts, "i", intern->increment); ADD_ASSOC_ZVAL_EX(return_value, "$timestamp", ts); } #endif } /* }}} */ /* {{{ proto string MongoDB\BSON\Timestamp::serialize() */ static PHP_METHOD(Timestamp, serialize) { php_phongo_timestamp_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval *retval; #endif php_serialize_data_t var_hash; smart_str buf = { 0 }; char s_increment[12]; char s_timestamp[12]; int s_increment_len; int s_timestamp_len; intern = Z_TIMESTAMP_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } s_increment_len = snprintf(s_increment, sizeof(s_increment), "%" PRIu32, intern->increment); s_timestamp_len = snprintf(s_timestamp, sizeof(s_timestamp), "%" PRIu32, intern->timestamp); #if PHP_VERSION_ID >= 70000 array_init_size(&retval, 2); ADD_ASSOC_STRINGL(&retval, "increment", s_increment, s_increment_len); ADD_ASSOC_STRINGL(&retval, "timestamp", s_timestamp, s_timestamp_len); #else ALLOC_INIT_ZVAL(retval); array_init_size(retval, 2); ADD_ASSOC_STRINGL(retval, "increment", s_increment, s_increment_len); ADD_ASSOC_STRINGL(retval, "timestamp", s_timestamp, s_timestamp_len); #endif PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC); smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); PHONGO_RETVAL_SMART_STR(buf); smart_str_free(&buf); zval_ptr_dtor(&retval); } /* }}} */ /* {{{ proto void MongoDB\BSON\Timestamp::unserialize(string $serialized) */ static PHP_METHOD(Timestamp, unserialize) { php_phongo_timestamp_t *intern; zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; #if PHP_VERSION_ID >= 70000 zval props; #else zval *props; #endif php_unserialize_data_t var_hash; intern = Z_TIMESTAMP_OBJ_P(getThis()); zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); #if PHP_VERSION_ID < 70000 ALLOC_INIT_ZVAL(props); #endif PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&props); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_timestamp_ce->name)); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #if PHP_VERSION_ID >= 70000 php_phongo_timestamp_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC); #else php_phongo_timestamp_init_from_hash(intern, HASH_OF(props) TSRMLS_CC); #endif zval_ptr_dtor(&props); } /* }}} */ /* {{{ MongoDB\BSON\Timestamp function entries */ 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___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp_void, 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, __set_state, ai_Timestamp___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(Timestamp, __toString, ai_Timestamp_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Timestamp, jsonSerialize, ai_Timestamp_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Timestamp, serialize, ai_Timestamp_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Timestamp, unserialize, ai_Timestamp_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Timestamp, getIncrement, ai_Timestamp_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Timestamp, getTimestamp, ai_Timestamp_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\Timestamp object handlers */ static zend_object_handlers php_phongo_handler_timestamp; 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 (intern->properties) { zend_hash_destroy(intern->properties); FREE_HASHTABLE(intern->properties); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static int php_phongo_timestamp_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_timestamp_t *intern1, *intern2; intern1 = Z_TIMESTAMP_OBJ_P(o1); intern2 = Z_TIMESTAMP_OBJ_P(o2); /* MongoDB compares the timestamp before the increment. */ if (intern1->timestamp != intern2->timestamp) { return intern1->timestamp < intern2->timestamp ? -1 : 1; } if (intern1->increment != intern2->increment) { return intern1->increment < intern2->increment ? -1 : 1; } return 0; } /* }}} */ static HashTable *php_phongo_timestamp_get_gc(zval *object, phongo_get_gc_table table, int *n TSRMLS_DC) /* {{{ */ { *table = NULL; *n = 0; return Z_TIMESTAMP_OBJ_P(object)->properties; } /* }}} */ static HashTable *php_phongo_timestamp_get_properties_hash(zval *object, bool is_debug TSRMLS_DC) /* {{{ */ { php_phongo_timestamp_t *intern; HashTable *props; char s_increment[24]; char s_timestamp[24]; int s_increment_len; int s_timestamp_len; intern = Z_TIMESTAMP_OBJ_P(object); PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2); if (!intern->initialized) { return props; } s_increment_len = snprintf(s_increment, sizeof(s_increment), "%" PRIu32, intern->increment); s_timestamp_len = snprintf(s_timestamp, sizeof(s_timestamp), "%" PRIu32, intern->timestamp); #if PHP_VERSION_ID >= 70000 { zval increment, timestamp; ZVAL_STRINGL(&increment, s_increment, s_increment_len); zend_hash_str_update(props, "increment", sizeof("increment")-1, &increment); ZVAL_STRINGL(×tamp, s_timestamp, s_timestamp_len); zend_hash_str_update(props, "timestamp", sizeof("timestamp")-1, ×tamp); } #else { zval *increment, *timestamp; MAKE_STD_ZVAL(increment); ZVAL_STRINGL(increment, s_increment, s_increment_len, 1); zend_hash_update(props, "increment", sizeof("increment"), &increment, sizeof(increment), NULL); MAKE_STD_ZVAL(timestamp); ZVAL_STRINGL(timestamp, s_timestamp, s_timestamp_len, 1); zend_hash_update(props, "timestamp", sizeof("timestamp"), ×tamp, sizeof(timestamp), NULL); } #endif return props; } /* }}} */ static HashTable *php_phongo_timestamp_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { *is_temp = 1; return php_phongo_timestamp_get_properties_hash(object, true TSRMLS_CC); } /* }}} */ static HashTable *php_phongo_timestamp_get_properties(zval *object TSRMLS_DC) /* {{{ */ { return php_phongo_timestamp_get_properties_hash(object, false TSRMLS_CC); } /* }}} */ /* }}} */ void php_phongo_timestamp_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_timestamp_ce); zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, php_phongo_timestamp_interface_ce); zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, zend_ce_serializable); memcpy(&php_phongo_handler_timestamp, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_timestamp.compare_objects = php_phongo_timestamp_compare_objects; php_phongo_handler_timestamp.get_debug_info = php_phongo_timestamp_get_debug_info; php_phongo_handler_timestamp.get_gc = php_phongo_timestamp_get_gc; php_phongo_handler_timestamp.get_properties = php_phongo_timestamp_get_properties; #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 } /* }}} */ /* * 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.3.4/src/BSON/TimestampInterface.c0000664000175000017500000000321013210321137020251 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_timestamp_interface_ce; /* {{{ MongoDB\BSON\TimestampInterface function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_TimestampInterface_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_timestamp_interface_me[] = { ZEND_ABSTRACT_ME(TimestampInterface, getIncrement, ai_TimestampInterface_void) ZEND_ABSTRACT_ME(TimestampInterface, getTimestamp, ai_TimestampInterface_void) ZEND_ABSTRACT_ME(TimestampInterface, __toString, ai_TimestampInterface_void) PHP_FE_END }; /* }}} */ void php_phongo_timestamp_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "TimestampInterface", php_phongo_timestamp_interface_me); php_phongo_timestamp_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/Type.c0000664000175000017500000000234613210321137015417 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_type_ce; /* {{{ MongoDB\BSON\Type function entries */ static zend_function_entry php_phongo_type_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_type_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Type", php_phongo_type_me); php_phongo_type_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/UTCDateTime.c0000664000175000017500000004451513210321137016552 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif #ifdef PHP_WIN32 # include "win32/time.h" #endif #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_utcdatetime_ce; /* Initialize the object and return whether it was successful. */ static bool php_phongo_utcdatetime_init(php_phongo_utcdatetime_t *intern, int64_t milliseconds) /* {{{ */ { intern->milliseconds = milliseconds; intern->initialized = true; return true; } /* }}} */ /* Initialize the object from a numeric string and return whether it was * successful. An exception will be thrown on error. */ static bool php_phongo_utcdatetime_init_from_string(php_phongo_utcdatetime_t *intern, const char *s_milliseconds, phongo_zpp_char_len s_milliseconds_len TSRMLS_DC) /* {{{ */ { int64_t milliseconds; char *endptr = NULL; errno = 0; milliseconds = bson_ascii_strtoll(s_milliseconds, &endptr, 10); /* errno will set errno if conversion fails; however, we do not need to * specify the type of error. * * Note: bson_ascii_strtoll() does not properly detect out-of-range values * (see: CDRIVER-1377). strtoll() would be preferable, but it is not * available on all platforms (e.g. HP-UX), and atoll() provides no error * reporting at all. */ if (errno || (endptr && endptr != ((const char *)s_milliseconds + s_milliseconds_len))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing \"%s\" as 64-bit integer for %s initialization", s_milliseconds, ZSTR_VAL(php_phongo_utcdatetime_ce->name)); return false; } return php_phongo_utcdatetime_init(intern, milliseconds); } /* }}} */ /* Initialize the object from a HashTable and return whether it was successful. * An exception will be thrown on error. */ static bool php_phongo_utcdatetime_init_from_hash(php_phongo_utcdatetime_t *intern, HashTable *props TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *milliseconds; if ((milliseconds = zend_hash_str_find(props, "milliseconds", sizeof("milliseconds")-1)) && Z_TYPE_P(milliseconds) == IS_LONG) { return php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds)); } if ((milliseconds = zend_hash_str_find(props, "milliseconds", sizeof("milliseconds")-1)) && Z_TYPE_P(milliseconds) == IS_STRING) { return php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds) TSRMLS_CC); } #else zval **milliseconds; if (zend_hash_find(props, "milliseconds", sizeof("milliseconds"), (void**) &milliseconds) == SUCCESS && Z_TYPE_PP(milliseconds) == IS_LONG) { return php_phongo_utcdatetime_init(intern, Z_LVAL_PP(milliseconds)); } if (zend_hash_find(props, "milliseconds", sizeof("milliseconds"), (void**) &milliseconds) == SUCCESS && Z_TYPE_PP(milliseconds) == IS_STRING) { return php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_PP(milliseconds), Z_STRLEN_PP(milliseconds) TSRMLS_CC); } #endif phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"milliseconds\" integer or numeric string field", ZSTR_VAL(php_phongo_utcdatetime_ce->name)); return false; } /* }}} */ /* Initialize the object from the current time and return whether it was * successful. */ static bool php_phongo_utcdatetime_init_from_current_time(php_phongo_utcdatetime_t *intern) /* {{{ */ { int64_t sec, usec; struct timeval cur_time; gettimeofday(&cur_time, NULL); sec = cur_time.tv_sec; usec = cur_time.tv_usec; intern->milliseconds = (sec * 1000) + (usec / 1000); intern->initialized = true; return true; } /* }}} */ /* Initialize the object from a DateTime object and return whether it was * successful. */ static bool php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t *intern, php_date_obj *datetime_obj) /* {{{ */ { int64_t sec, usec; /* The following assignments use the same logic as date_format() in php_date.c */ sec = datetime_obj->time->sse; #if PHP_VERSION_ID >= 70200 usec = (int64_t) floor(datetime_obj->time->us); #else usec = (int64_t) floor(datetime_obj->time->f * 1000000 + 0.5); #endif intern->milliseconds = (sec * 1000) + (usec / 1000); intern->initialized = true; return true; } /* }}} */ /* {{{ proto void MongoDB\BSON\UTCDateTime::__construct([int|float|string|DateTimeInterface $milliseconds = null]) Construct a new BSON UTCDateTime type from either the current time, milliseconds since the epoch, or a DateTimeInterface object. Defaults to the current time. */ static PHP_METHOD(UTCDateTime, __construct) { php_phongo_utcdatetime_t *intern; zend_error_handling error_handling; zval *milliseconds = NULL; 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 (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &milliseconds) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (milliseconds == NULL) { php_phongo_utcdatetime_init_from_current_time(intern); return; } if (Z_TYPE_P(milliseconds) == IS_OBJECT) { if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_date_ce() TSRMLS_CC) || (php_phongo_date_immutable_ce && instanceof_function(Z_OBJCE_P(milliseconds), php_phongo_date_immutable_ce TSRMLS_CC))) { php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds)); } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(milliseconds)->name)); } return; } if (Z_TYPE_P(milliseconds) == IS_LONG) { php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds)); return; } if (Z_TYPE_P(milliseconds) == IS_DOUBLE) { char tmp[24]; int tmp_len; tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", Z_DVAL_P(milliseconds) > 0 ? floor(Z_DVAL_P(milliseconds)) : ceil(Z_DVAL_P(milliseconds))); php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len TSRMLS_CC); return; } if (Z_TYPE_P(milliseconds) != IS_STRING) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(milliseconds))); return; } php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds) TSRMLS_CC); } /* }}} */ /* {{{ proto void MongoDB\BSON\UTCDateTime::__set_state(array $properties) */ static PHP_METHOD(UTCDateTime, __set_state) { php_phongo_utcdatetime_t *intern; HashTable *props; zval *array; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { RETURN_FALSE; } object_init_ex(return_value, php_phongo_utcdatetime_ce); intern = Z_UTCDATETIME_OBJ_P(return_value); props = Z_ARRVAL_P(array); php_phongo_utcdatetime_init_from_hash(intern, props TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\BSON\UTCDateTime::__toString() Returns the UTCDateTime's milliseconds as a string */ static 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 DateTime MongoDB\BSON\UTCDateTime::toDateTime() Returns a DateTime object representing this UTCDateTime */ static PHP_METHOD(UTCDateTime, toDateTime) { php_phongo_utcdatetime_t *intern; php_date_obj *datetime_obj; char *sec; size_t sec_len; intern = Z_UTCDATETIME_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } object_init_ex(return_value, php_date_get_date_ce()); datetime_obj = Z_PHPDATE_P(return_value); sec_len = spprintf(&sec, 0, "@%" PRId64, intern->milliseconds / 1000); php_date_initialize(datetime_obj, sec, sec_len, NULL, NULL, 0 TSRMLS_CC); efree(sec); #if PHP_VERSION_ID >= 70200 datetime_obj->time->us = (intern->milliseconds % 1000) * 1000; #else datetime_obj->time->f = (double) (intern->milliseconds % 1000) / 1000; #endif } /* }}} */ /* {{{ proto array MongoDB\BSON\UTCDateTime::jsonSerialize() */ static PHP_METHOD(UTCDateTime, jsonSerialize) { php_phongo_utcdatetime_t *intern; char s_milliseconds[24]; int s_milliseconds_len; if (zend_parse_parameters_none() == FAILURE) { return; } intern = Z_UTCDATETIME_OBJ_P(getThis()); s_milliseconds_len = snprintf(s_milliseconds, sizeof(s_milliseconds), "%" PRId64, intern->milliseconds); array_init_size(return_value, 1); #if PHP_VERSION_ID >= 70000 { zval udt; array_init_size(&udt, 1); ADD_ASSOC_STRINGL(&udt, "$numberLong", s_milliseconds, s_milliseconds_len); ADD_ASSOC_ZVAL_EX(return_value, "$date", &udt); } #else { zval *udt; MAKE_STD_ZVAL(udt); array_init_size(udt, 1); ADD_ASSOC_STRINGL(udt, "$numberLong", s_milliseconds, s_milliseconds_len); ADD_ASSOC_ZVAL_EX(return_value, "$date", udt); } #endif } /* }}} */ /* {{{ proto string MongoDB\BSON\UTCDateTime::serialize() */ static PHP_METHOD(UTCDateTime, serialize) { php_phongo_utcdatetime_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval *retval; #endif php_serialize_data_t var_hash; smart_str buf = { 0 }; char s_milliseconds[24]; int s_milliseconds_len; intern = Z_UTCDATETIME_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } s_milliseconds_len = snprintf(s_milliseconds, sizeof(s_milliseconds), "%" PRId64, intern->milliseconds); #if PHP_VERSION_ID >= 70000 array_init_size(&retval, 2); ADD_ASSOC_STRINGL(&retval, "milliseconds", s_milliseconds, s_milliseconds_len); #else ALLOC_INIT_ZVAL(retval); array_init_size(retval, 2); ADD_ASSOC_STRINGL(retval, "milliseconds", s_milliseconds, s_milliseconds_len); #endif PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, &retval, &var_hash TSRMLS_CC); smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); PHONGO_RETVAL_SMART_STR(buf); smart_str_free(&buf); zval_ptr_dtor(&retval); } /* }}} */ /* {{{ proto void MongoDB\BSON\UTCDateTime::unserialize(string $serialized) */ static PHP_METHOD(UTCDateTime, unserialize) { php_phongo_utcdatetime_t *intern; zend_error_handling error_handling; char *serialized; phongo_zpp_char_len serialized_len; #if PHP_VERSION_ID >= 70000 zval props; #else zval *props; #endif php_unserialize_data_t var_hash; intern = Z_UTCDATETIME_OBJ_P(getThis()); zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &serialized, &serialized_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); #if PHP_VERSION_ID < 70000 ALLOC_INIT_ZVAL(props); #endif PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&props, (const unsigned char**) &serialized, (unsigned char *) serialized + serialized_len, &var_hash TSRMLS_CC)) { zval_ptr_dtor(&props); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s unserialization failed", ZSTR_VAL(php_phongo_utcdatetime_ce->name)); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); #if PHP_VERSION_ID >= 70000 php_phongo_utcdatetime_init_from_hash(intern, HASH_OF(&props) TSRMLS_CC); #else php_phongo_utcdatetime_init_from_hash(intern, HASH_OF(props) TSRMLS_CC); #endif zval_ptr_dtor(&props); } /* }}} */ /* {{{ MongoDB\BSON\UTCDateTime function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime___construct, 0, 0, 0) ZEND_ARG_INFO(0, milliseconds) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime___set_state, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, properties, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime_unserialize, 0, 0, 1) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime_void, 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, __set_state, ai_UTCDateTime___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(UTCDateTime, __toString, ai_UTCDateTime_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(UTCDateTime, jsonSerialize, ai_UTCDateTime_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(UTCDateTime, serialize, ai_UTCDateTime_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(UTCDateTime, unserialize, ai_UTCDateTime_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(UTCDateTime, toDateTime, ai_UTCDateTime_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\BSON\UTCDateTime object handlers */ static zend_object_handlers php_phongo_handler_utcdatetime; 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 (intern->properties) { zend_hash_destroy(intern->properties); FREE_HASHTABLE(intern->properties); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static int php_phongo_utcdatetime_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_utcdatetime_t *intern1, *intern2; intern1 = Z_UTCDATETIME_OBJ_P(o1); intern2 = Z_UTCDATETIME_OBJ_P(o2); if (intern1->milliseconds != intern2->milliseconds) { return intern1->milliseconds < intern2->milliseconds ? -1 : 1; } return 0; } /* }}} */ static HashTable *php_phongo_utcdatetime_get_gc(zval *object, phongo_get_gc_table table, int *n TSRMLS_DC) /* {{{ */ { *table = NULL; *n = 0; return Z_UTCDATETIME_OBJ_P(object)->properties; } /* }}} */ static HashTable *php_phongo_utcdatetime_get_properties_hash(zval *object, bool is_debug TSRMLS_DC) /* {{{ */ { php_phongo_utcdatetime_t *intern; HashTable *props; char s_milliseconds[24]; int s_milliseconds_len; intern = Z_UTCDATETIME_OBJ_P(object); PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, 2); if (!intern->initialized) { return props; } s_milliseconds_len = snprintf(s_milliseconds, sizeof(s_milliseconds), "%" PRId64, intern->milliseconds); #if PHP_VERSION_ID >= 70000 { zval milliseconds; ZVAL_STRINGL(&milliseconds, s_milliseconds, s_milliseconds_len); zend_hash_str_update(props, "milliseconds", sizeof("milliseconds")-1, &milliseconds); } #else { zval *milliseconds; MAKE_STD_ZVAL(milliseconds); ZVAL_STRINGL(milliseconds, s_milliseconds, s_milliseconds_len, 1); zend_hash_update(props, "milliseconds", sizeof("milliseconds"), &milliseconds, sizeof(milliseconds), NULL); } #endif return props; } /* }}} */ static HashTable *php_phongo_utcdatetime_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { *is_temp = 1; return php_phongo_utcdatetime_get_properties_hash(object, true TSRMLS_CC); } /* }}} */ static HashTable *php_phongo_utcdatetime_get_properties(zval *object TSRMLS_DC) /* {{{ */ { return php_phongo_utcdatetime_get_properties_hash(object, false TSRMLS_CC); } /* }}} */ /* }}} */ void php_phongo_utcdatetime_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "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_FINAL(php_phongo_utcdatetime_ce); zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, php_phongo_utcdatetime_interface_ce); zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, php_phongo_json_serializable_ce); zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, php_phongo_type_ce); zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, zend_ce_serializable); memcpy(&php_phongo_handler_utcdatetime, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_utcdatetime.compare_objects = php_phongo_utcdatetime_compare_objects; php_phongo_handler_utcdatetime.get_debug_info = php_phongo_utcdatetime_get_debug_info; php_phongo_handler_utcdatetime.get_gc = php_phongo_utcdatetime_get_gc; php_phongo_handler_utcdatetime.get_properties = php_phongo_utcdatetime_get_properties; #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 } /* }}} */ /* * 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.3.4/src/BSON/UTCDateTimeInterface.c0000664000175000017500000000311613210321137020363 0ustar jmikolajmikola/* * Copyright 2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_utcdatetime_interface_ce; /* {{{ MongoDB\BSON\UTCDateTimeInterface function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTimeInterface_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_utcdatetime_interface_me[] = { ZEND_ABSTRACT_ME(UTCDateTimeInterface, toDateTime, ai_UTCDateTimeInterface_void) ZEND_ABSTRACT_ME(UTCDateTimeInterface, __toString, ai_UTCDateTimeInterface_void) PHP_FE_END }; /* }}} */ void php_phongo_utcdatetime_interface_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "UTCDateTimeInterface", php_phongo_utcdatetime_interface_me); php_phongo_utcdatetime_interface_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/Unserializable.c0000664000175000017500000000277313210321137017453 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_unserializable_ce; /* {{{ MongoDB\BSON\Unserializable function entries */ 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 }; /* }}} */ void php_phongo_unserializable_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "Unserializable", php_phongo_unserializable_me); php_phongo_unserializable_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/BSON/functions.c0000664000175000017500000001345713210321137016513 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" typedef enum { PHONGO_JSON_MODE_LEGACY, PHONGO_JSON_MODE_CANONICAL, PHONGO_JSON_MODE_RELAXED, } php_phongo_json_mode_t; /* {{{ proto string MongoDB\BSON\fromPHP(array|object $value) Returns the BSON representation of a PHP value */ PHP_FUNCTION(MongoDB_BSON_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(); php_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); } /* }}} */ /* {{{ proto array|object MongoDB\BSON\toPHP(string $bson [, array $typemap = array()]) Returns the PHP representation of a BSON value, optionally converting it into a custom class */ PHP_FUNCTION(MongoDB_BSON_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; } if (!php_phongo_bson_typemap_to_state(typemap, &state.map TSRMLS_CC)) { return; } if (!php_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 MongoDB\BSON\fromJSON(string $json) Returns the BSON representation of a JSON value */ PHP_FUNCTION(MongoDB_BSON_fromJSON) { char *json; phongo_zpp_char_len json_len; bson_t bson = 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", &json, &json_len) == FAILURE) { return; } if (bson_init_from_json(&bson, (const char *)json, json_len, &error)) { PHONGO_RETVAL_STRINGL((const char *) bson_get_data(&bson), bson.len); bson_destroy(&bson); } else { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s", error.domain == BSON_ERROR_JSON ? error.message : "Error parsing JSON"); } } /* }}} */ static void phongo_bson_to_json(INTERNAL_FUNCTION_PARAMETERS, php_phongo_json_mode_t mode) { char *data; phongo_zpp_char_len data_len; const bson_t *bson; bool eof = false; bson_reader_t *reader; char *json = NULL; size_t json_len; 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); bson = bson_reader_read(reader, NULL); if (!bson) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not read document from BSON reader"); bson_reader_destroy(reader); return; } if (mode == PHONGO_JSON_MODE_LEGACY) { json = bson_as_json(bson, &json_len); } else if (mode == PHONGO_JSON_MODE_CANONICAL) { json = bson_as_canonical_extended_json(bson, &json_len); } else if (mode == PHONGO_JSON_MODE_RELAXED) { json = bson_as_relaxed_extended_json(bson, &json_len); } if (!json) { 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(json, json_len); bson_free(json); 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 MongoDB\BSON\toJSON(string $bson) Returns the legacy extended JSON representation of a BSON value */ PHP_FUNCTION(MongoDB_BSON_toJSON) { phongo_bson_to_json(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHONGO_JSON_MODE_LEGACY); } /* }}} */ /* {{{ proto string MongoDB\BSON\toCanonicalExtendedJSON(string $bson) Returns the canonical extended JSON representation of a BSON value */ PHP_FUNCTION(MongoDB_BSON_toCanonicalExtendedJSON) { phongo_bson_to_json(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHONGO_JSON_MODE_CANONICAL); } /* }}} */ /* {{{ proto string MongoDB\BSON\toRelaxedExtendedJSON(string $bson) Returns the relaxed extended JSON representation of a BSON value */ PHP_FUNCTION(MongoDB_BSON_toRelaxedExtendedJSON) { phongo_bson_to_json(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHONGO_JSON_MODE_RELAXED); } /* }}} */ /* * 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.3.4/src/BSON/functions.h0000664000175000017500000000212113210321137016502 0ustar jmikolajmikola/* * Copyright 2014-2017 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 PHONGO_BSON_FUNCTIONS_H #define PHONGO_BSON_FUNCTIONS_H #include PHP_FUNCTION(MongoDB_BSON_fromPHP); PHP_FUNCTION(MongoDB_BSON_toPHP); PHP_FUNCTION(MongoDB_BSON_fromJSON); PHP_FUNCTION(MongoDB_BSON_toJSON); PHP_FUNCTION(MongoDB_BSON_toCanonicalExtendedJSON); PHP_FUNCTION(MongoDB_BSON_toRelaxedExtendedJSON); #endif /* PHONGO_BSON_FUNCTIONS_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.3.4/src/MongoDB/Exception/AuthenticationException.c0000664000175000017500000000310713210321137024012 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_authenticationexception_ce; /* {{{ MongoDB\Driver\Exception\AuthenticationException function entries */ static zend_function_entry php_phongo_authenticationexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_authenticationexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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 } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/BulkWriteException.c0000664000175000017500000000302513210321137022742 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_bulkwriteexception_ce; /* {{{ MongoDB\Driver\Exception\BulkWriteException function entries */ static zend_function_entry php_phongo_bulkwriteexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_bulkwriteexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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 } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/ConnectionException.c0000664000175000017500000000304113210321137023127 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_connectionexception_ce; /* {{{ MongoDB\Driver\Exception\ConnectionException function entries */ static zend_function_entry php_phongo_connectionexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_connectionexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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 } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/ConnectionTimeoutException.c0000664000175000017500000000323313210321137024501 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_connectiontimeoutexception_ce; /* {{{ MongoDB\Driver\Exception\ConnectionTimeoutException function entries */ static zend_function_entry php_phongo_connectiontimeoutexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_connectiontimeoutexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_connectiontimeoutexception_ce); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/Exception.c0000664000175000017500000000244213210321137021113 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_exception_ce; /* {{{ MongoDB\Driver\Exception\Exception function entries */ static zend_function_entry php_phongo_exception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_exception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "Exception", php_phongo_exception_me); php_phongo_exception_ce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/ExecutionTimeoutException.c0000664000175000017500000000321413210321137024344 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_executiontimeoutexception_ce; /* {{{ MongoDB\Driver\Exception\ExecutionTimeoutException function entries */ static zend_function_entry php_phongo_executiontimeoutexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_executiontimeoutexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_executiontimeoutexception_ce); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/InvalidArgumentException.c0000664000175000017500000000332513210321137024126 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_invalidargumentexception_ce; /* {{{ MongoDB\Driver\Exception\InvalidArgumentException function entries */ static zend_function_entry php_phongo_invalidargumentexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_invalidargumentexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/LogicException.c0000664000175000017500000000314713210321137022074 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_logicexception_ce; /* {{{ MongoDB\Driver\Exception\LogicException function entries */ static zend_function_entry php_phongo_logicexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_logicexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/RuntimeException.c0000664000175000017500000000317513210321137022463 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_runtimeexception_ce; /* {{{ MongoDB\Driver\Exception\RuntimeException function entries */ static zend_function_entry php_phongo_runtimeexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_runtimeexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/SSLConnectionException.c0000664000175000017500000000316713210321137023522 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_sslconnectionexception_ce; /* {{{ MongoDB\Driver\Exception\SSLConnectionException function entries */ static zend_function_entry php_phongo_sslconnectionexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_sslconnectionexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_sslconnectionexception_ce); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/UnexpectedValueException.c0000664000175000017500000000332513210321137024136 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_unexpectedvalueexception_ce; /* {{{ MongoDB\Driver\Exception\UnexpectedValueException function entries */ static zend_function_entry php_phongo_unexpectedvalueexception_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_unexpectedvalueexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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); } /* }}} */ /* * 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.3.4/src/MongoDB/Exception/WriteException.c0000664000175000017500000000500013210321137022117 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_writeexception_ce; /* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Exception\WriteException::getWriteResult() Returns the WriteResult from the failed write operation. */ static 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); } /* }}} */ /* {{{ MongoDB\Driver\Exception\WriteException function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteException_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_writeexception_me[] = { PHP_ME(WriteException, getWriteResult, ai_WriteException_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ void php_phongo_writeexception_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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); } /* }}} */ /* * 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.3.4/src/MongoDB/Monitoring/CommandFailedEvent.c0000664000175000017500000002136013210321137023031 0ustar jmikolajmikola/* * Copyright 2016-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_commandfailedevent_ce; /* {{{ proto string CommandFailedEvent::getCommandName() Returns the command name for this event */ PHP_METHOD(CommandFailedEvent, getCommandName) { php_phongo_commandfailedevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETVAL_STRING(intern->command_name); } /* }}} */ /* {{{ proto int CommandFailedEvent::getDurationMicros() Returns the event's duration in microseconds */ PHP_METHOD(CommandFailedEvent, getDurationMicros) { php_phongo_commandfailedevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->duration_micros); } /* }}} */ /* {{{ proto Exception CommandFailedEvent::getError() Returns the error document associated with the event */ PHP_METHOD(CommandFailedEvent, getError) { php_phongo_commandfailedevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&intern->z_error, 1, 0); #else RETURN_ZVAL(intern->z_error, 1, 0); #endif } /* }}} */ /* {{{ proto string CommandFailedEvent::getOperationId() Returns the event's operation ID */ PHP_METHOD(CommandFailedEvent, getOperationId) { php_phongo_commandfailedevent_t *intern; char int_as_string[20]; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } sprintf(int_as_string, "%" PHONGO_LONG_FORMAT, intern->operation_id); PHONGO_RETVAL_STRING(int_as_string); } /* }}} */ /* {{{ proto string CommandFailedEvent::getRequestId() Returns the event's request ID */ PHP_METHOD(CommandFailedEvent, getRequestId) { php_phongo_commandfailedevent_t *intern; char int_as_string[20]; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } sprintf(int_as_string, "%" PHONGO_LONG_FORMAT, intern->request_id); PHONGO_RETVAL_STRING(int_as_string); } /* }}} */ /* {{{ proto MongoDB\Driver\Server CommandFailedEvent::getServer() Returns the Server from which the event originated */ PHP_METHOD(CommandFailedEvent, getServer) { php_phongo_commandfailedevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDFAILEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC); } /* }}} */ /** * Event thrown when a command has failed to execute. * * This class is only constructed internally. */ /* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_CommandFailedEvent_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_commandfailedevent_me[] = { ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandFailedEvent_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) PHP_ME(CommandFailedEvent, getCommandName, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandFailedEvent, getError, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandFailedEvent, getDurationMicros, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandFailedEvent, getOperationId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandFailedEvent, getRequestId, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandFailedEvent, getServer, ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandFailedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Monitoring\CommandFailedEvent object handlers */ static zend_object_handlers php_phongo_handler_commandfailedevent; static void php_phongo_commandfailedevent_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_commandfailedevent_t *intern = Z_OBJ_COMMANDFAILEDEVENT(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (!Z_ISUNDEF(intern->z_error)) { zval_ptr_dtor(&intern->z_error); } if (intern->command_name) { efree(intern->command_name); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static phongo_create_object_retval php_phongo_commandfailedevent_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_commandfailedevent_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_commandfailedevent_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_commandfailedevent; 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_commandfailedevent_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_commandfailedevent; return retval; } #endif } /* }}} */ static HashTable *php_phongo_commandfailedevent_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_commandfailedevent_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif char operation_id[20], request_id[20]; intern = Z_COMMANDFAILEDEVENT_OBJ_P(object); *is_temp = 1; array_init_size(&retval, 6); ADD_ASSOC_STRING(&retval, "commandName", intern->command_name); ADD_ASSOC_INT64(&retval, "durationMicros", intern->duration_micros); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "error", &intern->z_error); Z_ADDREF(intern->z_error); #else ADD_ASSOC_ZVAL_EX(&retval, "error", intern->z_error); Z_ADDREF_P(intern->z_error); #endif sprintf(operation_id, "%" PHONGO_LONG_FORMAT, intern->operation_id); ADD_ASSOC_STRING(&retval, "operationId", operation_id); sprintf(request_id, "%" PHONGO_LONG_FORMAT, intern->request_id); ADD_ASSOC_STRING(&retval, "requestId", request_id); { #if PHP_VERSION_ID >= 70000 zval server; phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", &server); #else zval *server = NULL; MAKE_STD_ZVAL(server); phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", server); #endif } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandFailedEvent", php_phongo_commandfailedevent_me); php_phongo_commandfailedevent_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_commandfailedevent_ce->create_object = php_phongo_commandfailedevent_create_object; PHONGO_CE_FINAL(php_phongo_commandfailedevent_ce); PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandfailedevent_ce); memcpy(&php_phongo_handler_commandfailedevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_commandfailedevent.get_debug_info = php_phongo_commandfailedevent_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_commandfailedevent.free_obj = php_phongo_commandfailedevent_free_object; php_phongo_handler_commandfailedevent.offset = XtOffsetOf(php_phongo_commandfailedevent_t, std); #endif return; } /* }}} */ /* * 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.3.4/src/MongoDB/Monitoring/CommandStartedEvent.c0000664000175000017500000002217013210321137023253 0ustar jmikolajmikola/* * Copyright 2016-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_commandstartedevent_ce; /* {{{ proto stdClass CommandStartedEvent::getCommand() Returns the command document associated with the event */ PHP_METHOD(CommandStartedEvent, getCommand) { php_phongo_commandstartedevent_t *intern; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } php_phongo_bson_to_zval_ex(bson_get_data(intern->command), intern->command->len, &state); #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } /* }}} */ /* {{{ proto string CommandStartedEvent::getCommandName() Returns the command name for this event */ PHP_METHOD(CommandStartedEvent, getCommandName) { php_phongo_commandstartedevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETVAL_STRING(intern->command_name); } /* }}} */ /* {{{ proto string CommandStartedEvent::getDatabaseName() Returns the database name for this event */ PHP_METHOD(CommandStartedEvent, getDatabaseName) { php_phongo_commandstartedevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETVAL_STRING(intern->database_name); } /* }}} */ /* {{{ proto string CommandStartedEvent::getOperationId() Returns the event's operation ID */ PHP_METHOD(CommandStartedEvent, getOperationId) { php_phongo_commandstartedevent_t *intern; char int_as_string[20]; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } sprintf(int_as_string, "%" PHONGO_LONG_FORMAT, intern->operation_id); PHONGO_RETVAL_STRING(int_as_string); } /* }}} */ /* {{{ proto string CommandStartedEvent::getRequestId() Returns the event's request ID */ PHP_METHOD(CommandStartedEvent, getRequestId) { php_phongo_commandstartedevent_t *intern; char int_as_string[20]; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } sprintf(int_as_string, "%" PHONGO_LONG_FORMAT, intern->request_id); PHONGO_RETVAL_STRING(int_as_string); } /* }}} */ /* {{{ proto MongoDB\Driver\Server CommandStartedEvent::getServer() Returns the Server from which the event originated */ PHP_METHOD(CommandStartedEvent, getServer) { php_phongo_commandstartedevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSTARTEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC); } /* }}} */ /** * Event thrown when a command has started to execute. * * This class is only constructed internally. */ /* {{{ MongoDB\Driver\Monitoring\CommandStartedEvent function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_CommandStartedEvent_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_commandstartedevent_me[] = { ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandStartedEvent_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) PHP_ME(CommandStartedEvent, getCommand, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandStartedEvent, getCommandName, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandStartedEvent, getDatabaseName, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandStartedEvent, getOperationId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandStartedEvent, getRequestId, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandStartedEvent, getServer, ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandStartedEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Monitoring\CommandStartedEvent object handlers */ static zend_object_handlers php_phongo_handler_commandstartedevent; static void php_phongo_commandstartedevent_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_commandstartedevent_t *intern = Z_OBJ_COMMANDSTARTEDEVENT(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->command) { bson_destroy(intern->command); } if (intern->command_name) { efree(intern->command_name); } if (intern->database_name) { efree(intern->database_name); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static phongo_create_object_retval php_phongo_commandstartedevent_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_commandstartedevent_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_commandstartedevent_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_commandstartedevent; 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_commandstartedevent_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_commandstartedevent; return retval; } #endif } /* }}} */ static HashTable *php_phongo_commandstartedevent_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_commandstartedevent_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif char operation_id[20], request_id[20]; php_phongo_bson_state command_state = PHONGO_BSON_STATE_INITIALIZER; intern = Z_COMMANDSTARTEDEVENT_OBJ_P(object); *is_temp = 1; array_init_size(&retval, 6); php_phongo_bson_to_zval_ex(bson_get_data(intern->command), intern->command->len, &command_state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL(&retval, "command", &command_state.zchild); #else ADD_ASSOC_ZVAL(&retval, "command", command_state.zchild); #endif ADD_ASSOC_STRING(&retval, "commandName", intern->command_name); ADD_ASSOC_STRING(&retval, "databaseName", intern->database_name); sprintf(operation_id, "%" PHONGO_LONG_FORMAT, intern->operation_id); ADD_ASSOC_STRING(&retval, "operationId", operation_id); sprintf(request_id, "%" PHONGO_LONG_FORMAT, intern->request_id); ADD_ASSOC_STRING(&retval, "requestId", request_id); { #if PHP_VERSION_ID >= 70000 zval server; phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", &server); #else zval *server = NULL; MAKE_STD_ZVAL(server); phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", server); #endif } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_commandstartedevent_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandStartedEvent", php_phongo_commandstartedevent_me); php_phongo_commandstartedevent_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_commandstartedevent_ce->create_object = php_phongo_commandstartedevent_create_object; PHONGO_CE_FINAL(php_phongo_commandstartedevent_ce); PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandstartedevent_ce); memcpy(&php_phongo_handler_commandstartedevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_commandstartedevent.get_debug_info = php_phongo_commandstartedevent_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_commandstartedevent.free_obj = php_phongo_commandstartedevent_free_object; php_phongo_handler_commandstartedevent.offset = XtOffsetOf(php_phongo_commandstartedevent_t, std); #endif return; } /* }}} */ /* * 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.3.4/src/MongoDB/Monitoring/CommandSubscriber.c0000664000175000017500000000443713210321137022754 0ustar jmikolajmikola/* * Copyright 2016-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_commandsubscriber_ce; /* {{{ MongoDB\Driver\Monitoring\CommandSubscriber function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_CommandSubscriber_commandStarted, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, event, MongoDB\\Driver\\Monitoring\\CommandStartedEvent, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_CommandSubscriber_commandSucceeded, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, event, MongoDB\\Driver\\Monitoring\\CommandSucceededEvent, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_CommandSubscriber_commandFailed, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, event, MongoDB\\Driver\\Monitoring\\CommandFailedEvent, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_commandsubscriber_me[] = { ZEND_ABSTRACT_ME(CommandSubscriber, commandStarted, ai_CommandSubscriber_commandStarted) ZEND_ABSTRACT_ME(CommandSubscriber, commandSucceeded, ai_CommandSubscriber_commandSucceeded) ZEND_ABSTRACT_ME(CommandSubscriber, commandFailed, ai_CommandSubscriber_commandFailed) PHP_FE_END }; /* }}} */ void php_phongo_commandsubscriber_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandSubscriber", php_phongo_commandsubscriber_me); php_phongo_commandsubscriber_ce = zend_register_internal_interface(&ce TSRMLS_CC); zend_class_implements(php_phongo_commandsubscriber_ce TSRMLS_CC, 1, php_phongo_subscriber_ce); return; } /* }}} */ /* * 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.3.4/src/MongoDB/Monitoring/CommandSucceededEvent.c0000664000175000017500000002225213210321137023532 0ustar jmikolajmikola/* * Copyright 2016-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_commandsucceededevent_ce; /* {{{ proto string CommandSucceededEvent::getCommandName() Returns the command name for this event */ PHP_METHOD(CommandSucceededEvent, getCommandName) { php_phongo_commandsucceededevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETVAL_STRING(intern->command_name); } /* }}} */ /* {{{ proto int CommandSucceededEvent::getDurationMicros() Returns the event's duration in microseconds */ PHP_METHOD(CommandSucceededEvent, getDurationMicros) { php_phongo_commandsucceededevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->duration_micros); } /* }}} */ /* {{{ proto string CommandSucceededEvent::getOperationId() Returns the event's operation ID */ PHP_METHOD(CommandSucceededEvent, getOperationId) { php_phongo_commandsucceededevent_t *intern; char int_as_string[20]; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } sprintf(int_as_string, "%" PHONGO_LONG_FORMAT, intern->operation_id); PHONGO_RETVAL_STRING(int_as_string); } /* }}} */ /* {{{ proto stdClass CommandSucceededEvent::getReply() Returns the reply document associated with the event */ PHP_METHOD(CommandSucceededEvent, getReply) { php_phongo_commandsucceededevent_t *intern; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &state); #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } /* }}} */ /* {{{ proto string CommandsucceededEvent::getRequestId() Returns the event's request ID */ PHP_METHOD(CommandSucceededEvent, getRequestId) { php_phongo_commandsucceededevent_t *intern; char int_as_string[20]; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } sprintf(int_as_string, "%" PHONGO_LONG_FORMAT, intern->request_id); PHONGO_RETVAL_STRING(int_as_string); } /* }}} */ /* {{{ proto MongoDB\Driver\Server CommandSucceededEvent::getServer() Returns the Server from which the event originated */ PHP_METHOD(CommandSucceededEvent, getServer) { php_phongo_commandsucceededevent_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC); } /* }}} */ /** * Event thrown when a command has succeeded to execute. * * This class is only constructed internally. */ /* {{{ MongoDB\Driver\Monitoring\CommandSucceededEvent function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_CommandSucceededEvent_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_commandsucceededevent_me[] = { ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CommandSucceededEvent_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) PHP_ME(CommandSucceededEvent, getCommandName, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandSucceededEvent, getDurationMicros, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandSucceededEvent, getOperationId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandSucceededEvent, getReply, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandSucceededEvent, getRequestId, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(CommandSucceededEvent, getServer, ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CommandSucceededEvent_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Monitoring\CommandSucceededEvent object handlers */ static zend_object_handlers php_phongo_handler_commandsucceededevent; static void php_phongo_commandsucceededevent_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_commandsucceededevent_t *intern = Z_OBJ_COMMANDSUCCEEDEDEVENT(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->reply) { bson_destroy(intern->reply); } if (intern->command_name) { efree(intern->command_name); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static phongo_create_object_retval php_phongo_commandsucceededevent_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_commandsucceededevent_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_commandsucceededevent_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_commandsucceededevent; 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_commandsucceededevent_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_commandsucceededevent; return retval; } #endif } /* }}} */ static HashTable *php_phongo_commandsucceededevent_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_commandsucceededevent_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif char operation_id[20], request_id[20]; php_phongo_bson_state reply_state = PHONGO_BSON_STATE_INITIALIZER; intern = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(object); *is_temp = 1; array_init_size(&retval, 6); ADD_ASSOC_STRING(&retval, "commandName", intern->command_name); ADD_ASSOC_INT64(&retval, "durationMicros", intern->duration_micros); sprintf(operation_id, "%" PHONGO_LONG_FORMAT, intern->operation_id); ADD_ASSOC_STRING(&retval, "operationId", operation_id); php_phongo_bson_to_zval_ex(bson_get_data(intern->reply), intern->reply->len, &reply_state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL(&retval, "reply", &reply_state.zchild); #else ADD_ASSOC_ZVAL(&retval, "reply", reply_state.zchild); #endif sprintf(request_id, "%" PHONGO_LONG_FORMAT, intern->request_id); ADD_ASSOC_STRING(&retval, "requestId", request_id); { #if PHP_VERSION_ID >= 70000 zval server; phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", &server); #else zval *server = NULL; MAKE_STD_ZVAL(server); phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", server); #endif } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "CommandSucceededEvent", php_phongo_commandsucceededevent_me); php_phongo_commandsucceededevent_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_commandsucceededevent_ce->create_object = php_phongo_commandsucceededevent_create_object; PHONGO_CE_FINAL(php_phongo_commandsucceededevent_ce); PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_commandsucceededevent_ce); memcpy(&php_phongo_handler_commandsucceededevent, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_commandsucceededevent.get_debug_info = php_phongo_commandsucceededevent_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_commandsucceededevent.free_obj = php_phongo_commandsucceededevent_free_object; php_phongo_handler_commandsucceededevent.offset = XtOffsetOf(php_phongo_commandsucceededevent_t, std); #endif return; } /* }}} */ /* * 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.3.4/src/MongoDB/Monitoring/Subscriber.c0000664000175000017500000000257013210321137021451 0ustar jmikolajmikola/* * Copyright 2016-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_subscriber_ce; /* {{{ MongoDB\Driver\Monitoring\Subscriber function entries */ static zend_function_entry php_phongo_subscriber_me[] = { PHP_FE_END }; /* }}} */ void php_phongo_subscriber_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Monitoring", "Subscriber", php_phongo_subscriber_me); php_phongo_subscriber_ce = zend_register_internal_interface(&ce TSRMLS_CC); return; } /* }}} */ /* * 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.3.4/src/MongoDB/Monitoring/functions.c0000664000175000017500000000676713210321137021372 0ustar jmikolajmikola/* * Copyright 2016-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include "phongo_compat.h" #include "php_phongo.h" ZEND_EXTERN_MODULE_GLOBALS(mongodb) static char *php_phongo_make_subscriber_hash(zval *subscriber TSRMLS_DC) { char *hash; int hash_len; hash_len = spprintf(&hash, 0, "SUBS-%09d", Z_OBJ_HANDLE_P(subscriber)); return hash; } /* {{{ proto void MongoDB\Driver\Monitoring\addSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber) Adds a monitoring subscriber to the set of subscribers */ PHP_FUNCTION(MongoDB_Driver_Monitoring_addSubscriber) { zval *zSubscriber = NULL; char *hash; #if PHP_VERSION_ID >= 70000 zval *subscriber; #else zval **subscriber; #endif SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) { return; } /* The HashTable should never be NULL, as it's initialized during RINIT and * destroyed during RSHUTDOWN. This is simply a defensive guard. */ if (!MONGODB_G(subscribers)) { return; } hash = php_phongo_make_subscriber_hash(zSubscriber TSRMLS_CC); /* If we have already stored the subscriber, bail out. Otherwise, add * subscriber to list */ #if PHP_VERSION_ID >= 70000 if ((subscriber = zend_hash_str_find(MONGODB_G(subscribers), hash, strlen(hash)))) { efree(hash); return; } zend_hash_str_update(MONGODB_G(subscribers), hash, strlen(hash), zSubscriber); #else if (zend_hash_find(MONGODB_G(subscribers), hash, strlen(hash) + 1, (void**) &subscriber) == SUCCESS) { efree(hash); return; } zend_hash_update(MONGODB_G(subscribers), hash, strlen(hash) + 1, (void*) &zSubscriber, sizeof(zval*), NULL); #endif Z_ADDREF_P(zSubscriber); efree(hash); } /* }}} */ /* {{{ proto void MongoDB\Driver\Monitoring\removeSubscriber(MongoDB\Driver\Monitoring\Subscriber $subscriber) Removes a monitoring subscriber from the set of subscribers */ PHP_FUNCTION(MongoDB_Driver_Monitoring_removeSubscriber) { zval *zSubscriber = NULL; char *hash; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zSubscriber, php_phongo_subscriber_ce) == FAILURE) { return; } /* The HashTable should never be NULL, as it's initialized during RINIT and * destroyed during RSHUTDOWN. This is simply a defensive guard. */ if (!MONGODB_G(subscribers)) { return; } hash = php_phongo_make_subscriber_hash(zSubscriber TSRMLS_CC); #if PHP_VERSION_ID >= 70000 zend_hash_str_del(MONGODB_G(subscribers), hash, strlen(hash)); #else zend_hash_del(MONGODB_G(subscribers), hash, strlen(hash) + 1); #endif efree(hash); } /* }}} */ /* * 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.3.4/src/MongoDB/Monitoring/functions.h0000664000175000017500000000173713210321137021367 0ustar jmikolajmikola/* * Copyright 2016-2017 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 PHONGO_MONITORING_FUNCTIONS_H #define PHONGO_MONITORING_FUNCTIONS_H #include PHP_FUNCTION(MongoDB_Driver_Monitoring_addSubscriber); PHP_FUNCTION(MongoDB_Driver_Monitoring_removeSubscriber); #endif /* PHONGO_MONITORING_FUNCTIONS_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.3.4/src/MongoDB/BulkWrite.c0000664000175000017500000004345213210321137017135 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include "php_array_api.h" #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" #define PHONGO_BULKWRITE_BYPASS_UNSET -1 zend_class_entry *php_phongo_bulkwrite_ce; /* Returns whether the insert document appears to be a legacy index. */ static inline bool php_phongo_bulkwrite_insert_is_legacy_index(bson_t *bdocument) /* {{{ */ { bson_iter_t iter; if (bson_iter_init_find(&iter, bdocument, "key") && BSON_ITER_HOLDS_DOCUMENT(&iter) && bson_iter_init_find(&iter, bdocument, "name") && BSON_ITER_HOLDS_UTF8(&iter) && bson_iter_init_find(&iter, bdocument, "ns") && BSON_ITER_HOLDS_UTF8(&iter)) { return true; } return false; } /* }}} */ /* Extracts the "_id" field of a BSON document into a return value. */ static void php_phongo_bulkwrite_extract_id(bson_t *doc, zval **return_value) /* {{{ */ { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; zval *id = NULL; state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; if (!php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &state)) { goto cleanup; } #if PHP_VERSION_ID >= 70000 id = php_array_fetchc(&state.zchild, "_id"); #else id = php_array_fetchc(state.zchild, "_id"); #endif if (id) { ZVAL_ZVAL(*return_value, id, 1, 0); } cleanup: zval_ptr_dtor(&state.zchild); } /* }}} */ /* Returns whether any top-level field names in the document contain a "$". */ static inline bool php_phongo_bulkwrite_update_has_operators(bson_t *bupdate) /* {{{ */ { bson_iter_t iter; if (bson_iter_init(&iter, bupdate)) { while (bson_iter_next (&iter)) { if (strchr(bson_iter_key(&iter), '$')) { return true; } } } return false; } /* }}} */ /* Appends a document field for the given opts document and key. Returns true on * success; otherwise, false is returned and an exception is thrown. */ static bool php_phongo_bulkwrite_opts_append_document(bson_t *opts, const char *opts_key, zval *zarr, const char *zarr_key TSRMLS_DC) /* {{{ */ { zval *value = php_array_fetch(zarr, zarr_key); bson_t b = BSON_INITIALIZER; if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" option to be array or object, %s given", zarr_key, zend_get_type_by_const(Z_TYPE_P(value))); return false; } php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL TSRMLS_CC); if (EG(exception)) { bson_destroy(&b); return false; } if (!BSON_APPEND_DOCUMENT(opts, opts_key, &b)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", opts_key); bson_destroy(&b); return false; } bson_destroy(&b); return true; } /* }}} */ #define PHONGO_BULKWRITE_APPEND_BOOL(opt, value) \ if (!BSON_APPEND_BOOL(boptions, (opt), (value))) { \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \ return false; \ } #define PHONGO_BULKWRITE_APPEND_INT32(opt, value) \ if (!BSON_APPEND_INT32(boptions, (opt), (value))) { \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \ return false; \ } #define PHONGO_BULKWRITE_OPT_DOCUMENT(opt) \ if (zoptions && php_array_existsc(zoptions, (opt))) { \ if (!php_phongo_bulkwrite_opts_append_document(boptions, (opt), zoptions, (opt) TSRMLS_CC)) { \ return false; \ } \ } /* Applies options (including defaults) for an update operation. */ static bool php_phongo_bulkwrite_update_apply_options(bson_t *boptions, zval *zoptions TSRMLS_DC)/* {{{ */ { bool multi = false, upsert = false; if (zoptions) { if (php_array_existsc(zoptions, "multi")) { multi = php_array_fetchc_bool(zoptions, "multi"); } if (php_array_existsc(zoptions, "upsert")) { upsert = php_array_fetchc_bool(zoptions, "upsert"); } } PHONGO_BULKWRITE_APPEND_BOOL("multi", multi); PHONGO_BULKWRITE_APPEND_BOOL("upsert", upsert); PHONGO_BULKWRITE_OPT_DOCUMENT("collation"); return true; } /* }}} */ /* Applies options (including defaults) for an delete operation. */ static bool php_phongo_bulkwrite_delete_apply_options(bson_t *boptions, zval *zoptions TSRMLS_DC)/* {{{ */ { int32_t limit = 0; if (zoptions) { if (php_array_existsc(zoptions, "limit")) { limit = php_array_fetchc_bool(zoptions, "limit") ? 1 : 0; } } PHONGO_BULKWRITE_APPEND_INT32("limit", limit); PHONGO_BULKWRITE_OPT_DOCUMENT("collation"); return true; } /* }}} */ #undef PHONGO_BULKWRITE_APPEND_BOOL #undef PHONGO_BULKWRITE_APPEND_INT32 #undef PHONGO_BULKWRITE_OPT_DOCUMENT /* {{{ proto void MongoDB\Driver\BulkWrite::__construct([array $options = array()]) Constructs a new BulkWrite */ static 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_existsc(options, "ordered")) { ordered = php_array_fetchc_bool(options, "ordered"); } intern->bulk = phongo_bulkwrite_init(ordered); intern->ordered = ordered; intern->bypass = PHONGO_BULKWRITE_BYPASS_UNSET; intern->num_ops = 0; if (options && php_array_existsc(options, "bypassDocumentValidation")) { zend_bool bypass = php_array_fetchc_bool(options, "bypassDocumentValidation"); mongoc_bulk_operation_set_bypass_document_validation(intern->bulk, bypass); intern->bypass = bypass; } } /* }}} */ /* {{{ proto mixed MongoDB\Driver\BulkWrite::insert(array|object $document) Adds an insert operation to the BulkWrite */ static PHP_METHOD(BulkWrite, insert) { php_phongo_bulkwrite_t *intern; zval *zdocument; bson_t bdocument = BSON_INITIALIZER, boptions = BSON_INITIALIZER; bson_t *bson_out = NULL; int bson_flags = PHONGO_BSON_ADD_ID; bson_error_t error = {0}; 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", &zdocument) == FAILURE) { return; } if (return_value_used) { bson_flags |= PHONGO_BSON_RETURN_ID; } php_phongo_zval_to_bson(zdocument, bson_flags, &bdocument, &bson_out TSRMLS_CC); if (EG(exception)) { goto cleanup; } /* If the insert document appears to be a legacy index, instruct libmongoc * to allow dots in BSON keys by setting the "legacyIndex" option. * * Note: php_phongo_zval_to_bson() may have added an ObjectId if the "_id" * field was unset. We don't know at this point if the insert is destined * for a pre-2.6 server's "system.indexes" collection, but legacy index * creation will ignore the "_id" so there is no harm in leaving it. In the * event php_phongo_bulkwrite_insert_is_legacy_index() returns a false * positive, we absolutely want ObjectId added if "_id" was unset. */ if (php_phongo_bulkwrite_insert_is_legacy_index(&bdocument) && !BSON_APPEND_BOOL(&boptions, "legacyIndex", true)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"legacyIndex\" option"); goto cleanup; } if (!mongoc_bulk_operation_insert_with_opts(intern->bulk, &bdocument, &boptions, &error)) { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); goto cleanup; } intern->num_ops++; if (bson_out && return_value_used) { php_phongo_bulkwrite_extract_id(bson_out, &return_value); } cleanup: bson_destroy(&bdocument); bson_destroy(&boptions); bson_clear(&bson_out); } /* }}} */ /* {{{ proto void MongoDB\Driver\BulkWrite::update(array|object $query, array|object $newObj[, array $updateOptions = array()]) Adds an update operation to the BulkWrite */ static PHP_METHOD(BulkWrite, update) { php_phongo_bulkwrite_t *intern; zval *zquery, *zupdate, *zoptions = NULL; bson_t bquery = BSON_INITIALIZER, bupdate = BSON_INITIALIZER, boptions = BSON_INITIALIZER; bson_error_t error = {0}; 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!", &zquery, &zupdate, &zoptions) == FAILURE) { return; } php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL TSRMLS_CC); if (EG(exception)) { goto cleanup; } php_phongo_zval_to_bson(zupdate, PHONGO_BSON_NONE, &bupdate, NULL TSRMLS_CC); if (EG(exception)) { goto cleanup; } if (!php_phongo_bulkwrite_update_apply_options(&boptions, zoptions TSRMLS_CC)) { goto cleanup; } if (php_phongo_bulkwrite_update_has_operators(&bupdate)) { if (zoptions && php_array_existsc(zoptions, "multi") && php_array_fetchc_bool(zoptions, "multi")) { if (!mongoc_bulk_operation_update_many_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); goto cleanup; } } else { if (!mongoc_bulk_operation_update_one_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); goto cleanup; } } } else { if (zoptions && php_array_existsc(zoptions, "multi") && php_array_fetchc_bool(zoptions, "multi")) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Replacement document conflicts with true \"multi\" option"); goto cleanup; } if (!mongoc_bulk_operation_replace_one_with_opts(intern->bulk, &bquery, &bupdate, &boptions, &error)) { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); goto cleanup; } } intern->num_ops++; cleanup: bson_destroy(&bquery); bson_destroy(&bupdate); bson_destroy(&boptions); } /* }}} */ /* {{{ proto void MongoDB\Driver\BulkWrite::delete(array|object $query[, array $deleteOptions = array()]) Adds a delete operation to the BulkWrite */ static PHP_METHOD(BulkWrite, delete) { php_phongo_bulkwrite_t *intern; zval *zquery, *zoptions = NULL; bson_t bquery = BSON_INITIALIZER, boptions = BSON_INITIALIZER; bson_error_t error = {0}; 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!", &zquery, &zoptions) == FAILURE) { return; } php_phongo_zval_to_bson(zquery, PHONGO_BSON_NONE, &bquery, NULL TSRMLS_CC); if (EG(exception)) { goto cleanup; } if (!php_phongo_bulkwrite_delete_apply_options(&boptions, zoptions TSRMLS_CC)) { goto cleanup; } if (zoptions && php_array_existsc(zoptions, "limit") && php_array_fetchc_bool(zoptions, "limit")) { if (!mongoc_bulk_operation_remove_one_with_opts(intern->bulk, &bquery, &boptions, &error)) { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); goto cleanup; } } else { if (!mongoc_bulk_operation_remove_many_with_opts(intern->bulk, &bquery, &boptions, &error)) { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); goto cleanup; } } intern->num_ops++; cleanup: bson_destroy(&bquery); bson_destroy(&boptions); } /* }}} */ /* {{{ proto integer MongoDB\Driver\BulkWrite::count() Returns the number of operations that have been added to the BulkWrite */ static 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->num_ops); } /* }}} */ /* {{{ MongoDB\Driver\BulkWrite function entries */ 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_void, 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_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_BulkWrite_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\BulkWrite object handlers */ static zend_object_handlers php_phongo_handler_bulkwrite; 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 (intern->database) { efree(intern->database); } if (intern->collection) { efree(intern->collection); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static 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->database) { ADD_ASSOC_STRING(&retval, "database", intern->database); } else { ADD_ASSOC_NULL_EX(&retval, "database"); } if (intern->collection) { ADD_ASSOC_STRING(&retval, "collection", intern->collection); } else { ADD_ASSOC_NULL_EX(&retval, "collection"); } ADD_ASSOC_BOOL_EX(&retval, "ordered", intern->ordered); if (intern->bypass != PHONGO_BULKWRITE_BYPASS_UNSET) { ADD_ASSOC_BOOL_EX(&retval, "bypassDocumentValidation", intern->bypass); } else { ADD_ASSOC_NULL_EX(&retval, "bypassDocumentValidation"); } ADD_ASSOC_BOOL_EX(&retval, "executed", intern->executed); ADD_ASSOC_LONG_EX(&retval, "server_id", mongoc_bulk_operation_get_hint(intern->bulk)); if (mongoc_bulk_operation_get_write_concern(intern->bulk)) { #if PHP_VERSION_ID >= 70000 zval write_concern; php_phongo_write_concern_to_zval(&write_concern, mongoc_bulk_operation_get_write_concern(intern->bulk)); 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, mongoc_bulk_operation_get_write_concern(intern->bulk)); ADD_ASSOC_ZVAL_EX(&retval, "write_concern", write_concern); #endif } else { ADD_ASSOC_NULL_EX(&retval, "write_concern"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_bulkwrite_ce); PHONGO_CE_DISABLE_SERIALIZATION(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); } /* }}} */ /* * 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.3.4/src/MongoDB/Command.c0000664000175000017500000001172013210321137016574 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" zend_class_entry *php_phongo_command_ce; /* {{{ proto void MongoDB\Driver\Command::__construct(array|object $document) Constructs a new Command */ static 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); php_phongo_zval_to_bson(document, PHONGO_BSON_NONE, bson, NULL TSRMLS_CC); intern->bson = bson; } /* }}} */ /* {{{ MongoDB\Driver\Command function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_Command___construct, 0, 0, 1) ZEND_ARG_INFO(0, document) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Command_void, 0, 0, 0) 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) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Command_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Command object handlers */ static zend_object_handlers php_phongo_handler_command; 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 } /* }}} */ static 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 } /* }}} */ static 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 php_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); } /* }}} */ /* }}} */ void php_phongo_command_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_command_ce); PHONGO_CE_DISABLE_SERIALIZATION(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 } /* }}} */ /* * 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.3.4/src/MongoDB/Cursor.c0000664000175000017500000003616113210321137016501 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" zend_class_entry *php_phongo_cursor_ce; 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); ZVAL_UNDEF(&cursor->visitor_data.zchild); } } /* }}} */ /* {{{ MongoDB\Driver\Cursor iterator handlers */ 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; } /* }}} */ static void php_phongo_cursor_iterator_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor; ZVAL_LONG(key, cursor->current); } /* }}} */ #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->current++; if (mongoc_cursor_next(cursor->cursor, &doc)) { php_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->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) { php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data); } } /* }}} */ static 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 */ }; static 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; } /* }}} */ /* }}} */ /* {{{ proto void MongoDB\Driver\Cursor::setTypeMap(array $typemap) Sets a type map to use for BSON unserialization */ static PHP_METHOD(Cursor, setTypeMap) { php_phongo_cursor_t *intern; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; zval *typemap = NULL; bool restore_current_element = false; 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; } if (!php_phongo_bson_typemap_to_state(typemap, &state.map TSRMLS_CC)) { return; } /* Check if the existing element needs to be freed before we overwrite * visitor_data, which contains the only reference to it. */ if (!Z_ISUNDEF(intern->visitor_data.zchild)) { php_phongo_cursor_free_current(intern); restore_current_element = true; } intern->visitor_data = state; /* If the cursor has a current element, we just freed it and should restore * it with a new type map applied. */ if (restore_current_element && mongoc_cursor_current(intern->cursor)) { const bson_t *doc = mongoc_cursor_current(intern->cursor); php_phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &intern->visitor_data); } } /* }}} */ 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 MongoDB\Driver\Cursor::toArray() Returns an array of all result documents for this cursor */ static 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 MongoDB\Driver\Cursor::getId() Returns the CursorId for this cursor */ static 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 MongoDB\Driver\Cursor::getServer() Returns the Server object to which this cursor is attached */ static 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->client, intern->server_id TSRMLS_CC); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\Cursor::isDead() Checks if a cursor is still alive */ static 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 function entries */ 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_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_cursor_me[] = { PHP_ME(Cursor, setTypeMap, ai_Cursor_setTypeMap, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, toArray, ai_Cursor_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, getId, ai_Cursor_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, getServer, ai_Cursor_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, isDead, ai_Cursor_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Cursor_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Cursor_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Cursor object handlers */ static zend_object_handlers php_phongo_handler_cursor; 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); if (intern->cursor) { mongoc_cursor_destroy(intern->cursor); } if (intern->database) { efree(intern->database); } if (intern->collection) { efree(intern->collection); } if (!Z_ISUNDEF(intern->query)) { zval_ptr_dtor(&intern->query); } if (!Z_ISUNDEF(intern->command)) { zval_ptr_dtor(&intern->command); } if (!Z_ISUNDEF(intern->read_preference)) { zval_ptr_dtor(&intern->read_preference); } php_phongo_cursor_free_current(intern); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static 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, 9); if (intern->database) { ADD_ASSOC_STRING(&retval, "database", intern->database); } else { ADD_ASSOC_NULL_EX(&retval, "database"); } if (intern->collection) { ADD_ASSOC_STRING(&retval, "collection", intern->collection); } else { ADD_ASSOC_NULL_EX(&retval, "collection"); } if (!Z_ISUNDEF(intern->query)) { #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "query", &intern->query); Z_ADDREF(intern->query); #else ADD_ASSOC_ZVAL_EX(&retval, "query", intern->query); Z_ADDREF_P(intern->query); #endif } else { ADD_ASSOC_NULL_EX(&retval, "query"); } if (!Z_ISUNDEF(intern->command)) { #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "command", &intern->command); Z_ADDREF(intern->command); #else ADD_ASSOC_ZVAL_EX(&retval, "command", intern->command); Z_ADDREF_P(intern->command); #endif } else { ADD_ASSOC_NULL_EX(&retval, "command"); } if (!Z_ISUNDEF(intern->read_preference)) { #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "readPreference", &intern->read_preference); Z_ADDREF(intern->read_preference); #else ADD_ASSOC_ZVAL_EX(&retval, "readPreference", intern->read_preference); Z_ADDREF_P(intern->read_preference); #endif } else { ADD_ASSOC_NULL_EX(&retval, "readPreference"); } ADD_ASSOC_BOOL_EX(&retval, "isDead", !mongoc_cursor_is_alive(intern->cursor)); ADD_ASSOC_LONG_EX(&retval, "currentIndex", intern->current); if (!Z_ISUNDEF(intern->visitor_data.zchild)) { #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "currentDocument", &intern->visitor_data.zchild); /*Z_ADDREF(intern->visitor_data.zchild);*/ #else ADD_ASSOC_ZVAL_EX(&retval, "currentDocument", intern->visitor_data.zchild); Z_ADDREF_P(intern->visitor_data.zchild); #endif } else { ADD_ASSOC_NULL_EX(&retval, "currentDocument"); } { #if PHP_VERSION_ID >= 70000 zval server; phongo_server_init(&server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", &server); #else zval *server = NULL; MAKE_STD_ZVAL(server); phongo_server_init(server, intern->client, intern->server_id TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "server", server); #endif } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_cursor_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_cursor_ce); PHONGO_CE_DISABLE_SERIALIZATION(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); } /* }}} */ /* * 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.3.4/src/MongoDB/CursorId.c0000664000175000017500000001061713210321137016754 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_cursorid_ce; /* {{{ proto string MongoDB\Driver\CursorId::__toString() Returns the string representation of the CursorId */ static PHP_METHOD(CursorId, __toString) { php_phongo_cursorid_t *intern; char *tmp; int tmp_len; 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; } tmp_len = spprintf(&tmp, 0, "%" PRId64, intern->id); PHONGO_RETVAL_STRINGL(tmp, tmp_len); efree(tmp); } /* }}} */ /* {{{ MongoDB\Driver\CursorId function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_CursorId_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_cursorid_me[] = { PHP_ME(CursorId, __toString, ai_CursorId_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_CursorId_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_CursorId_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\CursorId object handlers */ static zend_object_handlers php_phongo_handler_cursorid; 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 } /* }}} */ static 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 } /* }}} */ static 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); #if SIZEOF_LONG == 4 { char tmp[24]; int tmp_len; tmp_len = snprintf(tmp, sizeof(tmp), "%" PRId64, intern->id); ADD_ASSOC_STRINGL(&retval, "id", tmp, tmp_len); } #else ADD_ASSOC_LONG_EX(&retval, "id", intern->id); #endif return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_cursorid_ce); PHONGO_CE_DISABLE_SERIALIZATION(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 } /* }}} */ /* * 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.3.4/src/MongoDB/Manager.c0000664000175000017500000005207113210321137016574 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "php_array_api.h" #include "phongo_compat.h" #include "php_phongo.h" #define PHONGO_MANAGER_URI_DEFAULT "mongodb://127.0.0.1/" /** * 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. */ zend_class_entry *php_phongo_manager_ce; /* Checks if driverOptions contains a stream context resource in the "context" * key and incorporates any of its SSL options into the base array that did not * already exist (i.e. array union). The "context" key is then unset from the * base array. * * This handles the merging of any legacy SSL context options and also makes * driverOptions suitable for serialization by removing the resource zval. */ static bool php_phongo_manager_merge_context_options(zval *zdriverOptions TSRMLS_DC) /* {{{ */ { php_stream_context *context; zval *zcontext, *zcontextOptions; if (!php_array_existsc(zdriverOptions, "context")) { return true; } zcontext = php_array_fetchc(zdriverOptions, "context"); context = php_stream_context_from_zval(zcontext, 1); if (!context) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"context\" driver option is not a valid Stream-Context resource"); return false; } #if PHP_VERSION_ID >= 70000 zcontextOptions = php_array_fetchc_array(&context->options, "ssl"); #else zcontextOptions = php_array_fetchc_array(context->options, "ssl"); #endif if (!zcontextOptions) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Stream-Context resource does not contain \"ssl\" options array"); return false; } /* Perform array union (see: add_function() in zend_operators.c) */ #if PHP_VERSION_ID >= 70000 zend_hash_merge(Z_ARRVAL_P(zdriverOptions), Z_ARRVAL_P(zcontextOptions), zval_add_ref, 0); #else { zval *tmp; zend_hash_merge(Z_ARRVAL_P(zdriverOptions), Z_ARRVAL_P(zcontextOptions), (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); } #endif php_array_unsetc(zdriverOptions, "context"); return true; } /* }}} */ /* Prepare authMechanismProperties for BSON encoding by converting a boolean * value for the "CANONICALIZE_HOST_NAME" option to a string. * * Note: URI options are case-insensitive, so we must iterate through the * HashTable in order to detect options. */ static void php_phongo_manager_prep_authmechanismproperties(zval *properties TSRMLS_DC) /* {{{ */ { HashTable *ht_data; if (Z_TYPE_P(properties) != IS_ARRAY && Z_TYPE_P(properties) != IS_OBJECT) { return; } ht_data = HASH_OF(properties); #if PHP_VERSION_ID >= 70000 { zend_string *string_key = NULL; zend_ulong num_key = 0; zval *property; ZEND_HASH_FOREACH_KEY_VAL(ht_data, num_key, string_key, property) { if (!string_key) { continue; } /* URI options are case-insensitive */ if (!strcasecmp(ZSTR_VAL(string_key), "CANONICALIZE_HOST_NAME")) { ZVAL_DEREF(property); if (Z_TYPE_P(property) != IS_STRING && zend_is_true(property)) { SEPARATE_ZVAL_NOREF(property); ZVAL_NEW_STR(property, zend_string_init(ZEND_STRL("true"), 0)); } } } ZEND_HASH_FOREACH_END(); } #else { HashPosition pos; zval **property; for (zend_hash_internal_pointer_reset_ex(ht_data, &pos); zend_hash_get_current_data_ex(ht_data, (void **) &property, &pos) == SUCCESS; zend_hash_move_forward_ex(ht_data, &pos)) { char *string_key = NULL; uint string_key_len = 0; ulong num_key = 0; if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos)) { continue; } /* URI options are case-insensitive */ if (!strcasecmp(string_key, "CANONICALIZE_HOST_NAME")) { if (Z_TYPE_PP(property) != IS_STRING && zend_is_true(*property)) { SEPARATE_ZVAL_IF_NOT_REF(property); Z_TYPE_PP(property) = IS_STRING; Z_STRVAL_PP(property) = estrndup("true", sizeof("true")-1); Z_STRLEN_PP(property) = sizeof("true")-1; } } } } #endif return; } /* }}} */ /* Prepare URI options for BSON encoding. * * Read preference tag sets must be an array of documents. In order to ensure * that empty arrays serialize as empty documents, array elements will be * converted to objects. php_phongo_read_preference_tags_are_valid() handles * actual validation of the tag set structure. * * Auth mechanism properties must have string values, so a boolean true value * for the "CANONICALIZE_HOST_NAME" property will be converted to "true". * * Note: URI options are case-insensitive, so we must iterate through the * HashTable in order to detect options. */ static void php_phongo_manager_prep_uri_options(zval *options TSRMLS_DC) /* {{{ */ { HashTable *ht_data; if (Z_TYPE_P(options) != IS_ARRAY) { return; } ht_data = HASH_OF(options); #if PHP_VERSION_ID >= 70000 { zend_string *string_key = NULL; zend_ulong num_key = 0; zval *option; ZEND_HASH_FOREACH_KEY_VAL(ht_data, num_key, string_key, option) { if (!string_key) { continue; } if (!strcasecmp(ZSTR_VAL(string_key), MONGOC_URI_READPREFERENCETAGS)) { ZVAL_DEREF(option); SEPARATE_ZVAL_NOREF(option); php_phongo_read_preference_prep_tagsets(option TSRMLS_CC); continue; } if (!strcasecmp(ZSTR_VAL(string_key), MONGOC_URI_AUTHMECHANISMPROPERTIES)) { ZVAL_DEREF(option); SEPARATE_ZVAL_NOREF(option); php_phongo_manager_prep_authmechanismproperties(option TSRMLS_CC); continue; } } ZEND_HASH_FOREACH_END(); } #else { HashPosition pos; zval **option; for (zend_hash_internal_pointer_reset_ex(ht_data, &pos); zend_hash_get_current_data_ex(ht_data, (void **) &option, &pos) == SUCCESS; zend_hash_move_forward_ex(ht_data, &pos)) { char *string_key = NULL; uint string_key_len = 0; ulong num_key = 0; if (HASH_KEY_IS_STRING != zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos)) { continue; } if (!strcasecmp(string_key, MONGOC_URI_READPREFERENCETAGS)) { SEPARATE_ZVAL_IF_NOT_REF(option); php_phongo_read_preference_prep_tagsets(*option TSRMLS_CC); continue; } if (!strcasecmp(string_key, MONGOC_URI_AUTHMECHANISMPROPERTIES)) { SEPARATE_ZVAL_IF_NOT_REF(option); php_phongo_manager_prep_authmechanismproperties(*option TSRMLS_CC); continue; } } } #endif return; } /* }}} */ /* {{{ proto void MongoDB\Driver\Manager::__construct([string $uri = "mongodb://127.0.0.1/"[, array $options = array()[, array $driverOptions = array()]]]) Constructs a new Manager */ static 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; 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()); /* Separate the options and driverOptions zvals, since we may end up * modifying them in php_phongo_manager_prep_uri_options() and * php_phongo_manager_merge_context_options() below, respectively. */ 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) { php_phongo_manager_prep_uri_options(options TSRMLS_CC); } if (driverOptions && !php_phongo_manager_merge_context_options(driverOptions TSRMLS_CC)) { /* Exception should already have been thrown */ return; } phongo_manager_init(intern, uri_string ? uri_string : PHONGO_MANAGER_URI_DEFAULT, options, driverOptions TSRMLS_CC); if (intern->client) { php_phongo_set_monitoring_callbacks(intern->client); } } /* }}} */ /* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeCommand(string $db, MongoDB\Driver\Command $command[, MongoDB\Driver\ReadPreference $readPreference = null]) Execute a Command */ static PHP_METHOD(Manager, executeCommand) { php_phongo_manager_t *intern; char *db; phongo_zpp_char_len db_len; zval *command; zval *readPreference = NULL; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) 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; } intern = Z_MANAGER_OBJ_P(getThis()); phongo_execute_command(intern->client, db, command, readPreference, -1, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Manager::executeQuery(string $namespace, MongoDB\Driver\Query $query[, MongoDB\Driver\ReadPreference $readPreference = null]) Execute a Query */ static PHP_METHOD(Manager, executeQuery) { php_phongo_manager_t *intern; char *namespace; phongo_zpp_char_len namespace_len; zval *query; zval *readPreference = NULL; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &query, php_phongo_query_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) { return; } intern = Z_MANAGER_OBJ_P(getThis()); phongo_execute_query(intern->client, namespace, query, readPreference, -1, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, MongoDB\Driver\WriteConcern $writeConcern = null]) Executes a BulkWrite (i.e. any number of insert, update, and delete ops) */ static 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) 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; } intern = Z_MANAGER_OBJ_P(getThis()); bulk = Z_BULKWRITE_OBJ_P(zbulk); phongo_execute_write(intern->client, namespace, bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\ReadConcern MongoDB\Driver\Manager::getReadConcern() Returns the ReadConcern associated with this Manager */ static 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 MongoDB\Driver\Manager::getReadPreference() Returns the ReadPreference associated with this Manager */ static 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[] MongoDB\Driver\Manager::getServers() Returns the Servers associated with this Manager */ static PHP_METHOD(Manager, getServers) { php_phongo_manager_t *intern; mongoc_server_description_t **sds; size_t i, n = 0; 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; } sds = mongoc_client_get_server_descriptions(intern->client, &n); array_init_size(return_value, n); for (i = 0; i < n; i++) { #if PHP_VERSION_ID >= 70000 zval obj; phongo_server_init(&obj, intern->client, mongoc_server_description_id(sds[i]) TSRMLS_CC); add_next_index_zval(return_value, &obj); #else zval *obj = NULL; MAKE_STD_ZVAL(obj); phongo_server_init(obj, intern->client, mongoc_server_description_id(sds[i]) TSRMLS_CC); add_next_index_zval(return_value, obj); #endif } mongoc_server_descriptions_destroy_all(sds, n); } /* }}} */ /* {{{ proto MongoDB\Driver\WriteConcern MongoDB\Driver\Manager::getWriteConcern() Returns the WriteConcern associated with this Manager */ static 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 MongoDB\Driver\Manager::selectServers(MongoDB\Driver\ReadPreference $readPreference) Returns a suitable Server for the given ReadPreference */ static 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_client_select_server(intern->client, false, readPreference, &error); if (selected_server) { phongo_server_init(return_value, intern->client, mongoc_server_description_id(selected_server) 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); } } /* }}} */ /* {{{ MongoDB\Driver\Manager function entries */ 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_selectServer, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Manager_void, 0, 0, 0) 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_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, getReadPreference, ai_Manager_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, getServers, ai_Manager_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, getWriteConcern, ai_Manager_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, selectServer, ai_Manager_selectServer, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Manager_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Manager object handlers */ static zend_object_handlers php_phongo_handler_manager; 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_DEBUG("Not destroying persistent client for Manager"); intern->client = NULL; } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static HashTable *php_phongo_manager_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_manager_t *intern; mongoc_server_description_t **sds; size_t i, n = 0; #if PHP_VERSION_ID >= 70000 zval retval, cluster; #else zval retval = zval_used_for_init; zval *cluster = NULL; #endif *is_temp = 1; intern = Z_MANAGER_OBJ_P(object); array_init_size(&retval, 2); ADD_ASSOC_STRING(&retval, "uri", mongoc_uri_get_string(mongoc_client_get_uri(intern->client))); sds = mongoc_client_get_server_descriptions(intern->client, &n); #if PHP_VERSION_ID >= 70000 array_init_size(&cluster, n); for (i = 0; i < n; i++) { zval obj; php_phongo_server_to_zval(&obj, sds[i]); add_next_index_zval(&cluster, &obj); } ADD_ASSOC_ZVAL_EX(&retval, "cluster", &cluster); #else MAKE_STD_ZVAL(cluster); array_init_size(cluster, n); for (i = 0; i < n; i++) { zval *obj = NULL; MAKE_STD_ZVAL(obj); php_phongo_server_to_zval(obj, sds[i]); add_next_index_zval(cluster, obj); } ADD_ASSOC_ZVAL_EX(&retval, "cluster", cluster); #endif mongoc_server_descriptions_destroy_all(sds, n); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_manager_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_manager_ce); PHONGO_CE_DISABLE_SERIALIZATION(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 } /* }}} */ /* * 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.3.4/src/MongoDB/Query.c0000664000175000017500000004402113210321137016323 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "php_array_api.h" #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" zend_class_entry *php_phongo_query_ce; /* Appends a string field into the BSON options. Returns true on success; * otherwise, false is returned and an exception is thrown. */ static bool php_phongo_query_opts_append_string(bson_t *opts, const char *opts_key, zval *zarr, const char *zarr_key TSRMLS_DC) /* {{{ */ { zval *value = php_array_fetch(zarr, zarr_key); if (Z_TYPE_P(value) != IS_STRING) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" %s to be string, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", zend_get_type_by_const(Z_TYPE_P(value))); return false; } if (!bson_append_utf8(opts, opts_key, strlen(opts_key), Z_STRVAL_P(value), Z_STRLEN_P(value))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", opts_key); return false; } return true; } /* }}} */ /* Appends a document field for the given opts document and key. Returns true on * success; otherwise, false is returned and an exception is thrown. */ static bool php_phongo_query_opts_append_document(bson_t *opts, const char *opts_key, zval *zarr, const char *zarr_key TSRMLS_DC) /* {{{ */ { zval *value = php_array_fetch(zarr, zarr_key); bson_t b = BSON_INITIALIZER; if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"%s\" %s to be array or object, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", zend_get_type_by_const(Z_TYPE_P(value))); return false; } php_phongo_zval_to_bson(value, PHONGO_BSON_NONE, &b, NULL TSRMLS_CC); if (EG(exception)) { bson_destroy(&b); return false; } if (!bson_validate(&b, BSON_VALIDATE_EMPTY_KEYS, NULL)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot use empty keys in \"%s\" %s", zarr_key, zarr_key[0] == '$' ? "modifier" : "option"); bson_destroy(&b); return false; } if (!BSON_APPEND_DOCUMENT(opts, opts_key, &b)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", opts_key); bson_destroy(&b); return false; } bson_destroy(&b); return true; } /* }}} */ #define PHONGO_QUERY_OPT_BOOL(opt, zarr, key) \ if ((zarr) && php_array_existsc((zarr), (key))) { \ if (!BSON_APPEND_BOOL(intern->opts, (opt), php_array_fetchc_bool((zarr), (key)))) { \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \ return false; \ } \ } #define PHONGO_QUERY_OPT_DOCUMENT(opt, zarr, key) \ if ((zarr) && php_array_existsc((zarr), (key))) { \ if (!php_phongo_query_opts_append_document(intern->opts, (opt), (zarr), (key) TSRMLS_CC)) { \ return false; \ } \ } /* Note: handling of integer options will depend on SIZEOF_ZEND_LONG and we * are not converting strings to 64-bit integers for 32-bit platforms. */ #define PHONGO_QUERY_OPT_INT64(opt, zarr, key) \ if ((zarr) && php_array_existsc((zarr), (key))) { \ if (!BSON_APPEND_INT64(intern->opts, (opt), php_array_fetchc_long((zarr), (key)))) { \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"%s\" option", (opt)); \ return false; \ } \ } #define PHONGO_QUERY_OPT_STRING(opt, zarr, key) \ if ((zarr) && php_array_existsc((zarr), (key))) { \ if (!php_phongo_query_opts_append_string(intern->opts, (opt), (zarr), (key) TSRMLS_CC)) { \ return false; \ } \ } /* Initialize the "hint" option. Returns true on success; otherwise, false is * returned and an exception is thrown. * * The "hint" option (or "$hint" modifier) must be a string or document. Check * for both types and merge into BSON options accordingly. */ static bool php_phongo_query_init_hint(php_phongo_query_t *intern, zval *options, zval *modifiers TSRMLS_DC) /* {{{ */ { /* The "hint" option (or "$hint" modifier) must be a string or document. * Check for both types and merge into BSON options accordingly. */ if (php_array_existsc(options, "hint")) { zend_uchar type = Z_TYPE_P(php_array_fetchc(options, "hint")); if (type == IS_STRING) { PHONGO_QUERY_OPT_STRING("hint", options, "hint"); } else if (type == IS_OBJECT || type == IS_ARRAY) { PHONGO_QUERY_OPT_DOCUMENT("hint", options, "hint"); } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"hint\" option to be string, array, or object, %s given", zend_get_type_by_const(type)); return false; } } else if (modifiers && php_array_existsc(modifiers, "$hint")) { zend_uchar type = Z_TYPE_P(php_array_fetchc(modifiers, "$hint")); if (type == IS_STRING) { PHONGO_QUERY_OPT_STRING("hint", modifiers, "$hint"); } else if (type == IS_OBJECT || type == IS_ARRAY) { PHONGO_QUERY_OPT_DOCUMENT("hint", modifiers, "$hint"); } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"$hint\" modifier to be string, array, or object, %s given", zend_get_type_by_const(type)); return false; } } return true; } /* }}} */ /* Initialize the "limit" and "singleBatch" options. Returns true on success; * otherwise, false is returned and an exception is thrown. * * mongoc_collection_find_with_opts() requires a non-negative limit. For * backwards compatibility, a negative limit should be set as a positive value * and default singleBatch to true. */ static bool php_phongo_query_init_limit_and_singlebatch(php_phongo_query_t *intern, zval *options TSRMLS_DC) /* {{{ */ { if (php_array_existsc(options, "limit") && php_array_fetchc_long(options, "limit") < 0) { phongo_long limit = php_array_fetchc_long(options, "limit"); if (!BSON_APPEND_INT64(intern->opts, "limit", -limit)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"limit\" option"); return false; } if (php_array_existsc(options, "singleBatch") && !php_array_fetchc_bool(options, "singleBatch")) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Negative \"limit\" option conflicts with false \"singleBatch\" option"); return false; } else { if (!BSON_APPEND_BOOL(intern->opts, "singleBatch", true)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error appending \"singleBatch\" option"); return false; } } } else { PHONGO_QUERY_OPT_INT64("limit", options, "limit"); PHONGO_QUERY_OPT_BOOL("singleBatch", options, "singleBatch"); } return true; } /* }}} */ /* Initialize the "readConcern" option. Returns true on success; otherwise, * false is returned and an exception is thrown. * * The "readConcern" option should be a MongoDB\Driver\ReadConcern instance, * which must be converted to a mongoc_read_concern_t. */ static bool php_phongo_query_init_readconcern(php_phongo_query_t *intern, zval *options TSRMLS_DC) /* {{{ */ { if (php_array_existsc(options, "readConcern")) { zval *read_concern = php_array_fetchc(options, "readConcern"); if (Z_TYPE_P(read_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(read_concern), php_phongo_readconcern_ce TSRMLS_CC)) { 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(read_concern))); return false; } intern->read_concern = mongoc_read_concern_copy(phongo_read_concern_from_zval(read_concern TSRMLS_CC)); } return true; } /* }}} */ /* Initialize the "maxAwaitTimeMS" option. Returns true on success; otherwise, * false is returned and an exception is thrown. * * The "maxAwaitTimeMS" option is assigned to the cursor after query execution * via mongoc_cursor_set_max_await_time_ms(). */ static bool php_phongo_query_init_max_await_time_ms(php_phongo_query_t *intern, zval *options TSRMLS_DC) /* {{{ */ { if (php_array_existsc(options, "maxAwaitTimeMS")) { int64_t max_await_time_ms = php_array_fetchc_long(options, "maxAwaitTimeMS"); if (max_await_time_ms < 0) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxAwaitTimeMS\" option to be >= 0, %" PRId64 " given", max_await_time_ms); return false; } if (max_await_time_ms > UINT32_MAX) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"maxAwaitTimeMS\" option to be <= %" PRIu32 ", %" PRId64 " given", UINT32_MAX, max_await_time_ms); return false; } intern->max_await_time_ms = (uint32_t) max_await_time_ms; } return true; } /* }}} */ /* Initializes the php_phongo_query_t from filter and options arguments. This * function will fall back to a modifier in the absence of a top-level option * (where applicable). */ static bool php_phongo_query_init(php_phongo_query_t *intern, zval *filter, zval *options TSRMLS_DC) /* {{{ */ { zval *modifiers = NULL; intern->filter = bson_new(); intern->opts = bson_new(); php_phongo_zval_to_bson(filter, PHONGO_BSON_NONE, intern->filter, NULL TSRMLS_CC); /* Note: if any exceptions are thrown, we can simply return as PHP will * invoke php_phongo_query_free_object to destruct the object. */ if (EG(exception)) { return false; } if (!bson_validate(intern->filter, BSON_VALIDATE_EMPTY_KEYS, NULL)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot use empty keys in filter document"); return false; } if (!options) { return true; } if (php_array_existsc(options, "modifiers")) { modifiers = php_array_fetchc(options, "modifiers"); if (Z_TYPE_P(modifiers) != IS_ARRAY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"modifiers\" option to be array, %s given", zend_get_type_by_const(Z_TYPE_P(modifiers))); return false; } } PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "allowPartialResults") else PHONGO_QUERY_OPT_BOOL("allowPartialResults", options, "partial"); PHONGO_QUERY_OPT_BOOL("awaitData", options, "awaitData"); PHONGO_QUERY_OPT_INT64("batchSize", options, "batchSize"); PHONGO_QUERY_OPT_DOCUMENT("collation", options, "collation"); PHONGO_QUERY_OPT_STRING("comment", options, "comment") else PHONGO_QUERY_OPT_STRING("comment", modifiers, "$comment"); PHONGO_QUERY_OPT_BOOL("exhaust", options, "exhaust"); PHONGO_QUERY_OPT_DOCUMENT("max", options, "max") else PHONGO_QUERY_OPT_DOCUMENT("max", modifiers, "$max"); PHONGO_QUERY_OPT_INT64("maxScan", options, "maxScan") else PHONGO_QUERY_OPT_INT64("maxScan", modifiers, "$maxScan"); PHONGO_QUERY_OPT_INT64("maxTimeMS", options, "maxTimeMS") else PHONGO_QUERY_OPT_INT64("maxTimeMS", modifiers, "$maxTimeMS"); PHONGO_QUERY_OPT_DOCUMENT("min", options, "min") else PHONGO_QUERY_OPT_DOCUMENT("min", modifiers, "$min"); PHONGO_QUERY_OPT_BOOL("noCursorTimeout", options, "noCursorTimeout"); PHONGO_QUERY_OPT_BOOL("oplogReplay", options, "oplogReplay"); PHONGO_QUERY_OPT_DOCUMENT("projection", options, "projection"); PHONGO_QUERY_OPT_BOOL("returnKey", options, "returnKey") else PHONGO_QUERY_OPT_BOOL("returnKey", modifiers, "$returnKey"); PHONGO_QUERY_OPT_BOOL("showRecordId", options, "showRecordId") else PHONGO_QUERY_OPT_BOOL("showRecordId", modifiers, "$showDiskLoc"); PHONGO_QUERY_OPT_INT64("skip", options, "skip"); PHONGO_QUERY_OPT_DOCUMENT("sort", options, "sort") else PHONGO_QUERY_OPT_DOCUMENT("sort", modifiers, "$orderby"); PHONGO_QUERY_OPT_BOOL("snapshot", options, "snapshot") else PHONGO_QUERY_OPT_BOOL("snapshot", modifiers, "$snapshot"); PHONGO_QUERY_OPT_BOOL("tailable", options, "tailable"); /* The "$explain" modifier should be converted to an "explain" option, which * libmongoc will later convert back to a modifier for the OP_QUERY code * path. This modifier will be ignored for the find command code path. */ PHONGO_QUERY_OPT_BOOL("explain", modifiers, "$explain"); if (!php_phongo_query_init_hint(intern, options, modifiers TSRMLS_CC)) { return false; } if (!php_phongo_query_init_limit_and_singlebatch(intern, options TSRMLS_CC)) { return false; } if (!php_phongo_query_init_readconcern(intern, options TSRMLS_CC)) { return false; } if (!php_phongo_query_init_max_await_time_ms(intern, options TSRMLS_CC)) { return false; } return true; } /* }}} */ #undef PHONGO_QUERY_OPT_BOOL #undef PHONGO_QUERY_OPT_DOCUMENT #undef PHONGO_QUERY_OPT_INT64 #undef PHONGO_QUERY_OPT_STRING /* {{{ proto void MongoDB\Driver\Query::__construct(array|object $filter[, array $options = array()]) Constructs a new Query */ static PHP_METHOD(Query, __construct) { php_phongo_query_t *intern; zend_error_handling error_handling; zval *filter; zval *options = 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_QUERY_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A|a!", &filter, &options) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); php_phongo_query_init(intern, filter, options TSRMLS_CC); } /* }}} */ /* {{{ MongoDB\Driver\Query function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_Query___construct, 0, 0, 1) ZEND_ARG_INFO(0, filter) ZEND_ARG_ARRAY_INFO(0, options, 1) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_Query_void, 0, 0, 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) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Query_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Query object handlers */ static zend_object_handlers php_phongo_handler_query; 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->filter) { bson_clear(&intern->filter); } if (intern->opts) { bson_clear(&intern->opts); } if (intern->read_concern) { mongoc_read_concern_destroy(intern->read_concern); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static 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, 3); /* Avoid using PHONGO_TYPEMAP_NATIVE_ARRAY for decoding filter and opts * documents so that users can differentiate BSON arrays and documents. */ if (intern->filter) { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif php_phongo_bson_to_zval(bson_get_data(intern->filter), intern->filter->len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "filter", &zv); #else ADD_ASSOC_ZVAL_EX(&retval, "filter", zv); #endif } else { ADD_ASSOC_NULL_EX(&retval, "filter"); } if (intern->opts) { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif php_phongo_bson_to_zval(bson_get_data(intern->opts), intern->opts->len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "options", &zv); #else ADD_ASSOC_ZVAL_EX(&retval, "options", zv); #endif } else { ADD_ASSOC_NULL_EX(&retval, "options"); } 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); } /* }}} */ /* }}} */ void php_phongo_query_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_query_ce); PHONGO_CE_DISABLE_SERIALIZATION(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 } /* }}} */ /* * 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.3.4/src/MongoDB/ReadConcern.c0000664000175000017500000001567213210321137017413 0ustar jmikolajmikola/* * Copyright 2015-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_readconcern_ce; /* {{{ proto void MongoDB\Driver\ReadConcern::__construct([string $level]) Constructs a new ReadConcern */ static 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 MongoDB\Driver\ReadConcern::getLevel() Returns the ReadConcern "level" option */ static 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(); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\ReadConcern::isDefault() Returns whether the read concern has not been modified (i.e. constructed without a level or from a Manager with no read concern URI options). */ static PHP_METHOD(ReadConcern, isDefault) { php_phongo_readconcern_t *intern; 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; } RETURN_BOOL(mongoc_read_concern_is_default(intern->read_concern)); } /* }}} */ /* {{{ proto array MongoDB\Driver\ReadConcern::bsonSerialize() */ static PHP_METHOD(ReadConcern, bsonSerialize) { const mongoc_read_concern_t *read_concern = phongo_read_concern_from_zval(getThis() TSRMLS_CC); if (zend_parse_parameters_none() == FAILURE) { return; } php_phongo_read_concern_to_zval(return_value, read_concern); convert_to_object(return_value); } /* }}} */ /* {{{ MongoDB\Driver\ReadConcern function entries */ 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_void, 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_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadConcern, isDefault, ai_ReadConcern_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadConcern, bsonSerialize, ai_ReadConcern_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\ReadConcern object handlers */ static zend_object_handlers php_phongo_handler_readconcern; 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 } /* }}} */ static 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 } /* }}} */ static 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); } /* }}} */ /* }}} */ void php_phongo_readconcern_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_readconcern_ce); PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_readconcern_ce); zend_class_implements(php_phongo_readconcern_ce TSRMLS_CC, 1, php_phongo_serializable_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); zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("LINEARIZABLE"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE) TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/MongoDB/ReadPreference.c0000664000175000017500000003031713210321137020073 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "php_array_api.h" #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" zend_class_entry *php_phongo_readpreference_ce; /* {{{ proto void MongoDB\Driver\ReadPreference::__construct(int|string $mode[, array $tagSets = array()[, array $options = array()]]) Constructs a new ReadPreference */ static PHP_METHOD(ReadPreference, __construct) { php_phongo_readpreference_t *intern; zend_error_handling error_handling; zval *mode; zval *tagSets = NULL; zval *options = 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()); /* Separate the tagSets zval, since we may end up modifying it in * php_phongo_read_preference_prep_tagsets() below. */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a/!a!", &mode, &tagSets, &options) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (Z_TYPE_P(mode) == IS_LONG) { switch(Z_LVAL_P(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(Z_LVAL_P(mode)); break; default: phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid mode: %" PHONGO_LONG_FORMAT, Z_LVAL_P(mode)); return; } } else if (Z_TYPE_P(mode) == IS_STRING) { if (strcasecmp(Z_STRVAL_P(mode), "primary") == 0) { intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY); } else if (strcasecmp(Z_STRVAL_P(mode), "primaryPreferred") == 0) { intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_PRIMARY_PREFERRED); } else if (strcasecmp(Z_STRVAL_P(mode), "secondary") == 0) { intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY); } else if (strcasecmp(Z_STRVAL_P(mode), "secondaryPreferred") == 0) { intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_SECONDARY_PREFERRED); } else if (strcasecmp(Z_STRVAL_P(mode), "nearest") == 0) { intern->read_preference = mongoc_read_prefs_new(MONGOC_READ_NEAREST); } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid mode: '%s'", Z_STRVAL_P(mode)); return; } } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected mode to be integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(mode))); return; } if (tagSets) { bson_t *tags = bson_new(); php_phongo_read_preference_prep_tagsets(tagSets TSRMLS_CC); php_phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t *)tags, NULL TSRMLS_CC); if (!php_phongo_read_preference_tags_are_valid(tags)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets must be an array of zero or more documents"); bson_destroy(tags); return; } if (!bson_empty(tags) && (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets may not be used with primary mode"); bson_destroy(tags); return; } mongoc_read_prefs_set_tags(intern->read_preference, tags); bson_destroy(tags); } if (options && php_array_exists(options, "maxStalenessSeconds")) { phongo_long maxStalenessSeconds = php_array_fetchc_long(options, "maxStalenessSeconds"); if (maxStalenessSeconds != MONGOC_NO_MAX_STALENESS) { if (maxStalenessSeconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be >= %d, %" PHONGO_LONG_FORMAT " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, maxStalenessSeconds); return; } if (maxStalenessSeconds > INT32_MAX) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be <= %" PRId32 ", %" PHONGO_LONG_FORMAT " given", INT32_MAX, maxStalenessSeconds); return; } if (mongoc_read_prefs_get_mode(intern->read_preference) == MONGOC_READ_PRIMARY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "maxStalenessSeconds may not be used with primary mode"); return; } } mongoc_read_prefs_set_max_staleness_seconds(intern->read_preference, maxStalenessSeconds); } if (!mongoc_read_prefs_is_valid(intern->read_preference)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference is not valid"); return; } } /* }}} */ /* {{{ proto integer MongoDB\Driver\ReadPreference::getMaxStalenessSeconds() Returns the ReadPreference maxStalenessSeconds value */ static PHP_METHOD(ReadPreference, getMaxStalenessSeconds) { 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_max_staleness_seconds(intern->read_preference)); } /* }}} */ /* {{{ proto integer MongoDB\Driver\ReadPreference::getMode() Returns the ReadPreference mode */ static 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 MongoDB\Driver\ReadPreference::getTagSets() Returns the ReadPreference tag sets */ static PHP_METHOD(ReadPreference, getTagSets) { php_phongo_readpreference_t *intern; const bson_t *tags; 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; } tags = mongoc_read_prefs_get_tags(intern->read_preference); if (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; php_phongo_bson_to_zval_ex(bson_get_data(tags), 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(); } } /* }}} */ /* {{{ proto array MongoDB\Driver\ReadPreference::bsonSerialize() */ static PHP_METHOD(ReadPreference, bsonSerialize) { const mongoc_read_prefs_t *read_preference = phongo_read_preference_from_zval(getThis() TSRMLS_CC); if (zend_parse_parameters_none() == FAILURE) { return; } php_phongo_read_preference_to_zval(return_value, read_preference); convert_to_object(return_value); } /* }}} */ /* {{{ MongoDB\Driver\ReadPreference function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___construct, 0, 0, 1) ZEND_ARG_INFO(0, mode) ZEND_ARG_ARRAY_INFO(0, tagSets, 1) ZEND_ARG_ARRAY_INFO(0, options, 1) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_void, 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, getMaxStalenessSeconds, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadPreference, getMode, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadPreference, getTagSets, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadPreference, bsonSerialize, ai_ReadPreference_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\ReadPreference object handlers */ static zend_object_handlers php_phongo_handler_readpreference; 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 } /* }}} */ static 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 } /* }}} */ static 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); } /* }}} */ /* }}} */ void php_phongo_readpreference_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_readpreference_ce); PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_readpreference_ce); zend_class_implements(php_phongo_readpreference_ce TSRMLS_CC, 1, php_phongo_serializable_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); zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("NO_MAX_STALENESS"), MONGOC_NO_MAX_STALENESS TSRMLS_CC); zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("SMALLEST_MAX_STALENESS_SECONDS"), MONGOC_SMALLEST_MAX_STALENESS_SECONDS TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/MongoDB/Server.c0000664000175000017500000004752613210321137016501 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" zend_class_entry *php_phongo_server_ce; /* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Server::executeCommand(string $db, MongoDB\Driver\Command $command[, MongoDB\Driver\ReadPreference $readPreference = null])) Executes a Command on this Server */ static PHP_METHOD(Server, executeCommand) { php_phongo_server_t *intern; char *db; phongo_zpp_char_len db_len; zval *command; 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!", &db, &db_len, &command, php_phongo_command_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) { return; } phongo_execute_command(intern->client, db, command, readPreference, intern->server_id, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\Cursor MongoDB\Driver\Server::executeQuery(string $namespace, MongoDB\Driver\Query $query[, MongoDB\Driver\ReadPreference $readPreference = null])) Executes a Query on this Server */ static PHP_METHOD(Server, executeQuery) { php_phongo_server_t *intern; char *namespace; phongo_zpp_char_len namespace_len; zval *query; 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, &query, php_phongo_query_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) { return; } phongo_execute_query(intern->client, namespace, query, readPreference, intern->server_id, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\WriteResult MongoDB\Driver\Server::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, MongoDB\Driver\WriteConcern $writeConcern = null]) Executes a BulkWrite (i.e. any number of insert, update, and delete ops) on this Server */ static 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, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto string MongoDB\Driver\Server::getHost() Returns the hostname for this Server */ static PHP_METHOD(Server, getHost) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { PHONGO_RETVAL_STRING(mongoc_server_description_host(sd)->host); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto array MongoDB\Driver\Server::getTags() Returns the currently configured tags for this Server */ static PHP_METHOD(Server, getTags) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { const bson_t *is_master = mongoc_server_description_ismaster(sd); bson_iter_t iter; if (bson_iter_init_find(&iter, is_master, "tags") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { const uint8_t *bytes; uint32_t len; 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; bson_iter_document(&iter, &len, &bytes); if (!php_phongo_bson_to_zval_ex(bytes, len, &state)) { /* Exception should already have been thrown */ zval_ptr_dtor(&state.zchild); mongoc_server_description_destroy(sd); return; } mongoc_server_description_destroy(sd); #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } array_init(return_value); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto array MongoDB\Driver\Server::getInfo() Returns the last isMaster result document for this Server */ static PHP_METHOD(Server, getInfo) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { const bson_t *is_master = mongoc_server_description_ismaster(sd); 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; if (!php_phongo_bson_to_zval_ex(bson_get_data(is_master), is_master->len, &state)) { /* Exception should already have been thrown */ zval_ptr_dtor(&state.zchild); mongoc_server_description_destroy(sd); return; } mongoc_server_description_destroy(sd); #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"); } /* }}} */ /* {{{ proto integer MongoDB\Driver\Server::getLatency() Returns the last measured latency for this Server */ static PHP_METHOD(Server, getLatency) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { RETVAL_LONG((phongo_long) mongoc_server_description_round_trip_time(sd)); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto integer MongoDB\Driver\Server::getPort() Returns the port for this Server */ static PHP_METHOD(Server, getPort) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { RETVAL_LONG(mongoc_server_description_host(sd)->port); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto integer MongoDB\Driver\Server::getType() Returns the node type of this Server */ static PHP_METHOD(Server, getType) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { RETVAL_LONG(php_phongo_server_description_type(sd)); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\Server::isPrimary() Returns whether this Server is a primary member of a replica set */ static PHP_METHOD(Server, isPrimary) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_PRIMARY].name)); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\Server::isSecondary() Returns whether this Server is a secondary member of a replica set */ static PHP_METHOD(Server, isSecondary) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_SECONDARY].name)); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\Server::isArbiter() Returns whether this Server is an arbiter member of a replica set */ static PHP_METHOD(Server, isArbiter) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { RETVAL_BOOL(!strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_ARBITER].name)); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\Server::isHidden() Returns whether this Server is a hidden member of a replica set */ static PHP_METHOD(Server, isHidden) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { bson_iter_t iter; RETVAL_BOOL(bson_iter_init_find_case(&iter, mongoc_server_description_ismaster(sd), "hidden") && bson_iter_as_bool(&iter)); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\Server::isPassive() Returns whether this Server is a passive member of a replica set */ static PHP_METHOD(Server, isPassive) { php_phongo_server_t *intern; mongoc_server_description_t *sd; 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_client_get_server_description(intern->client, intern->server_id))) { bson_iter_t iter; RETVAL_BOOL(bson_iter_init_find_case(&iter, mongoc_server_description_ismaster(sd), "passive") && bson_iter_as_bool(&iter)); mongoc_server_description_destroy(sd); return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); } /* }}} */ /* {{{ MongoDB\Driver\Server function entries */ 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_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_server_me[] = { 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_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getTags, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getInfo, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getLatency, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getPort, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getType, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isPrimary, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isSecondary, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isArbiter, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isHidden, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isPassive, ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_Server_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_Server_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\Server object handlers */ static zend_object_handlers php_phongo_handler_server; static int php_phongo_server_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_server_t *intern1, *intern2; mongoc_server_description_t *sd1, *sd2; int retval = 0; intern1 = Z_SERVER_OBJ_P(o1); intern2 = Z_SERVER_OBJ_P(o2); sd1 = mongoc_client_get_server_description(intern1->client, intern1->server_id); sd2 = mongoc_client_get_server_description(intern2->client, intern2->server_id); if (sd1 && sd2) { retval = strcasecmp(mongoc_server_description_host(sd1)->host_and_port, mongoc_server_description_host(sd2)->host_and_port); } else { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description(s)"); } if (sd1) { mongoc_server_description_destroy(sd1); } if (sd2) { mongoc_server_description_destroy(sd2); } return retval; } /* }}} */ 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 } /* }}} */ static 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 } /* }}} */ static 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; *is_temp = 1; intern = Z_SERVER_OBJ_P(object); if (!(sd = mongoc_client_get_server_description(intern->client, intern->server_id))) { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description"); return NULL; } php_phongo_server_to_zval(&retval, sd); mongoc_server_description_destroy(sd); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_server_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_server_ce); PHONGO_CE_DISABLE_SERIALIZATION(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"), PHONGO_SERVER_UNKNOWN TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_STANDALONE"), PHONGO_SERVER_STANDALONE TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_MONGOS"), PHONGO_SERVER_MONGOS TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_POSSIBLE_PRIMARY"), PHONGO_SERVER_POSSIBLE_PRIMARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_PRIMARY"), PHONGO_SERVER_RS_PRIMARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_SECONDARY"), PHONGO_SERVER_RS_SECONDARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_ARBITER"), PHONGO_SERVER_RS_ARBITER TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_OTHER"), PHONGO_SERVER_RS_OTHER TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_GHOST"), PHONGO_SERVER_RS_GHOST TSRMLS_CC); } /* }}} */ /* * 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.3.4/src/MongoDB/WriteConcern.c0000664000175000017500000002325613210321137017627 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_writeconcern_ce; /* {{{ proto void MongoDB\Driver\WriteConcern::__construct(integer|string $w[, integer $wtimeout[, boolean $journal]]) Constructs a new WriteConcern */ static 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 MongoDB\Driver\WriteConcern::getW() Returns the WriteConcern "w" option */ static 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 (mongoc_write_concern_get_w(intern->write_concern) != MONGOC_WRITE_CONCERN_W_DEFAULT) { RETURN_LONG(mongoc_write_concern_get_w(intern->write_concern)); } RETURN_NULL(); } /* }}} */ /* {{{ proto integer MongoDB\Driver\WriteConcern::getWtimeout() Returns the WriteConcern "wtimeout" option */ static 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 MongoDB\Driver\WriteConcern::getJournal() Returns the WriteConcern "journal" option */ static 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 (mongoc_write_concern_journal_is_set(intern->write_concern)) { RETURN_BOOL(mongoc_write_concern_get_journal(intern->write_concern)); } RETURN_NULL(); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\WriteConcern::isDefault() Returns whether the write concern has not been modified (i.e. from a Manager with no write concern URI options). */ static PHP_METHOD(WriteConcern, isDefault) { 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_BOOL(mongoc_write_concern_is_default(intern->write_concern)); } /* }}} */ /* {{{ proto array MongoDB\Driver\WriteConcern::bsonSerialize() */ static PHP_METHOD(WriteConcern, bsonSerialize) { const mongoc_write_concern_t *write_concern = phongo_write_concern_from_zval(getThis() TSRMLS_CC); if (zend_parse_parameters_none() == FAILURE) { return; } php_phongo_write_concern_to_zval(return_value, write_concern); convert_to_object(return_value); } /* }}} */ /* {{{ MongoDB\Driver\WriteConcern function entries */ 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_void, 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_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcern, getWtimeout, ai_WriteConcern_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcern, getJournal, ai_WriteConcern_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcern, isDefault, ai_WriteConcern_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcern, bsonSerialize, ai_WriteConcern_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\WriteConcern object handlers */ static zend_object_handlers php_phongo_handler_writeconcern; 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 } /* }}} */ static 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 } /* }}} */ static 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); } /* }}} */ /* }}} */ void php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_writeconcern_ce); PHONGO_CE_DISABLE_SERIALIZATION(php_phongo_writeconcern_ce); zend_class_implements(php_phongo_writeconcern_ce TSRMLS_CC, 1, php_phongo_serializable_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); } /* }}} */ /* * 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.3.4/src/MongoDB/WriteConcernError.c0000664000175000017500000001355613210321137020643 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_writeconcernerror_ce; /* {{{ proto integer MongoDB\Driver\WriteConcernError::getCode() Returns the MongoDB error code */ static 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 MongoDB\Driver\WriteConcernError::getInfo() Returns additional metadata for the error */ static 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 MongoDB\Driver\WriteConcernError::getMessage() Returns the actual error message from the server */ static 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); } /* }}} */ /* {{{ MongoDB\Driver\WriteConcernError function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcernError_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_writeconcernerror_me[] = { PHP_ME(WriteConcernError, getCode, ai_WriteConcernError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcernError, getInfo, ai_WriteConcernError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcernError, getMessage, ai_WriteConcernError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_WriteConcernError_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_WriteConcernError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\WriteConcernError object handlers */ static zend_object_handlers php_phongo_handler_writeconcernerror; 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 } /* }}} */ static 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 } /* }}} */ static 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); } /* }}} */ /* }}} */ void php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_writeconcernerror_ce); PHONGO_CE_DISABLE_SERIALIZATION(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 } /* }}} */ /* * 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.3.4/src/MongoDB/WriteError.c0000664000175000017500000001376713210321137017337 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "phongo_compat.h" #include "php_phongo.h" zend_class_entry *php_phongo_writeerror_ce; /* {{{ proto integer MongoDB\Driver\WriteError::getCode() Returns the MongoDB error code */ static 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 MongoDB\Driver\WriteError::getIndex() Returns the index of the operation in the BulkWrite to which this WriteError corresponds. */ static 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 MongoDB\Driver\WriteError::getMessage() Returns the actual error message from the server */ static 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 MongoDB\Driver\WriteError::getInfo() Returns additional metadata for the error */ static 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 } } /* }}} */ /* {{{ MongoDB\Driver\WriteError function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteError_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_writeerror_me[] = { PHP_ME(WriteError, getCode, ai_WriteError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteError, getIndex, ai_WriteError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteError, getMessage, ai_WriteError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteError, getInfo, ai_WriteError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_WriteError_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_WriteError_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\WriteError object handlers */ static zend_object_handlers php_phongo_handler_writeerror; 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 } /* }}} */ static 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 } /* }}} */ static 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); } /* }}} */ /* }}} */ void php_phongo_writeerror_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_writeerror_ce); PHONGO_CE_DISABLE_SERIALIZATION(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 } /* }}} */ /* * 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.3.4/src/MongoDB/WriteResult.c0000664000175000017500000003775713210321137017531 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include "php_array_api.h" #include "phongo_compat.h" #include "php_phongo.h" #include "php_bson.h" #define PHONGO_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(iter, bson, key) \ if (bson_iter_init_find((iter), (bson), (key)) && BSON_ITER_HOLDS_INT32((iter))) { \ RETURN_LONG(bson_iter_int32((iter))); \ } zend_class_entry *php_phongo_writeresult_ce; static bool php_phongo_writeresult_get_writeconcernerror(php_phongo_writeresult_t *intern, zval *return_value TSRMLS_DC) /* {{{ */ { bson_iter_t iter, child; #if PHP_VERSION_ID >= 70000 zval writeconcernerror; #else zval *writeconcernerror = NULL; #endif ZVAL_NULL(return_value); if (bson_iter_init_find(&iter, intern->reply, "writeConcernErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) { while (bson_iter_next(&child)) { bson_t cbson; uint32_t len; const uint8_t *data; if (!BSON_ITER_HOLDS_DOCUMENT(&child)) { continue; } bson_iter_document(&child, &len, &data); if (!bson_init_static(&cbson, data, len)) { continue; } #if PHP_VERSION_ID >= 70000 if (!phongo_writeconcernerror_init(&writeconcernerror, &cbson TSRMLS_CC)) { zval_ptr_dtor(&writeconcernerror); return false; } ZVAL_ZVAL(return_value, &writeconcernerror, 1, 1); #else MAKE_STD_ZVAL(writeconcernerror); if (!phongo_writeconcernerror_init(writeconcernerror, &cbson TSRMLS_CC)) { zval_ptr_dtor(&writeconcernerror); return false; } ZVAL_ZVAL(return_value, writeconcernerror, 1, 1); #endif return true; } } return true; } /* }}} */ static bool php_phongo_writeresult_get_writeerrors(php_phongo_writeresult_t *intern, zval *return_value TSRMLS_DC) /* {{{ */ { bson_iter_t iter, child; array_init(return_value); if (bson_iter_init_find(&iter, intern->reply, "writeErrors") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) { while (bson_iter_next(&child)) { 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(&child)) { continue; } bson_iter_document(&child, &len, &data); if (!bson_init_static(&cbson, data, len)) { continue; } #if PHP_VERSION_ID >= 70000 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); if (!phongo_writeerror_init(writeerror, &cbson TSRMLS_CC)) { zval_ptr_dtor(&writeerror); continue; } add_next_index_zval(return_value, writeerror); #endif } } return true; } /* }}} */ /* {{{ proto integer|null MongoDB\Driver\WriteResult::getInsertedCount() Returns the number of documents that were inserted */ static PHP_METHOD(WriteResult, getInsertedCount) { bson_iter_t iter; 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_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nInserted"); } /* }}} */ /* {{{ proto integer|null MongoDB\Driver\WriteResult::getMatchedCount() Returns the number of documents that matched the update criteria */ static PHP_METHOD(WriteResult, getMatchedCount) { bson_iter_t iter; 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_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nMatched"); } /* }}} */ /* {{{ proto integer|null MongoDB\Driver\WriteResult::getModifiedCount() Returns the number of documents that were actually modified by an update */ static PHP_METHOD(WriteResult, getModifiedCount) { bson_iter_t iter; 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_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nModified"); } /* }}} */ /* {{{ proto integer|null MongoDB\Driver\WriteResult::getDeletedCount() Returns the number of documents that were deleted */ static PHP_METHOD(WriteResult, getDeletedCount) { bson_iter_t iter; 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_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nRemoved"); } /* }}} */ /* {{{ proto integer|null MongoDB\Driver\WriteResult::getUpsertedCount() Returns the number of documents that were upserted */ static PHP_METHOD(WriteResult, getUpsertedCount) { bson_iter_t iter; 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_WRITERESULT_RETURN_LONG_FROM_BSON_INT32(&iter, intern->reply, "nUpserted"); } /* }}} */ /* {{{ proto MongoDB\Driver\Server MongoDB\Driver\WriteResult::getServer() Returns the Server from which the result originated */ static 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 MongoDB\Driver\WriteResult::getUpsertedIds() Returns the identifiers generated by the server for upsert operations. */ static PHP_METHOD(WriteResult, getUpsertedIds) { bson_iter_t iter, child; 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_iter_init_find(&iter, intern->reply, "upserted") && BSON_ITER_HOLDS_ARRAY(&iter) && bson_iter_recurse(&iter, &child)) { while (bson_iter_next(&child)) { uint32_t data_len; const uint8_t *data = NULL; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; /* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type so we can * easily access the "index" and "_id" fields. */ state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; if (!BSON_ITER_HOLDS_DOCUMENT(&child)) { continue; } bson_iter_document(&child, &data_len, &data); if (php_phongo_bson_to_zval_ex(data, data_len, &state)) { #if PHP_VERSION_ID >= 70000 zval *zid = php_array_fetchc(&state.zchild, "_id"); add_index_zval(return_value, php_array_fetchc_long(&state.zchild, "index"), zid); zval_add_ref(zid); #else zval *zid = php_array_fetchc(state.zchild, "_id"); add_index_zval(return_value, php_array_fetchc_long(state.zchild, "index"), zid); zval_add_ref(&zid); #endif } zval_ptr_dtor(&state.zchild); } } } /* }}} */ /* {{{ proto WriteConcernError MongoDB\Driver\WriteResult::getWriteConcernError() Return any write concern error that occurred */ static 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; } php_phongo_writeresult_get_writeconcernerror(intern, return_value TSRMLS_CC); } /* }}} */ /* {{{ proto WriteError[] MongoDB\Driver\WriteResult::getWriteErrors() Returns any write errors that occurred */ static 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; } php_phongo_writeresult_get_writeerrors(intern, return_value TSRMLS_CC); } /* }}} */ /* {{{ proto boolean MongoDB\Driver\WriteResult::isAcknowledged() Returns whether the write operation was acknowledged (based on the write concern). */ static 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_is_acknowledged(intern->write_concern)); } /* }}} */ /* {{{ MongoDB\Driver\WriteResult function entries */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_void, 0, 0, 0) ZEND_END_ARG_INFO() static zend_function_entry php_phongo_writeresult_me[] = { PHP_ME(WriteResult, getInsertedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getMatchedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getModifiedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getDeletedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getUpsertedCount, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getServer, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getUpsertedIds, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getWriteConcernError, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getWriteErrors, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, isAcknowledged, ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_NAMED_ME(__construct, PHP_FN(MongoDB_disabled___construct), ai_WriteResult_void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_NAMED_ME(__wakeup, PHP_FN(MongoDB_disabled___wakeup), ai_WriteResult_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ MongoDB\Driver\WriteResult object handlers */ static zend_object_handlers php_phongo_handler_writeresult; 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); if (intern->reply) { bson_destroy(intern->reply); } if (intern->write_concern) { mongoc_write_concern_destroy(intern->write_concern); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ static 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 } /* }}} */ static 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 bson_iter_t iter; intern = Z_WRITERESULT_OBJ_P(object); *is_temp = 1; array_init_size(&retval, 9); #define PHONGO_WRITERESULT_SCP(field) \ if (bson_iter_init_find(&iter, intern->reply, (field)) && BSON_ITER_HOLDS_INT32(&iter)) { \ ADD_ASSOC_LONG_EX(&retval, (field), bson_iter_int32(&iter)); \ } else { \ ADD_ASSOC_NULL_EX(&retval, (field)); \ } PHONGO_WRITERESULT_SCP("nInserted"); PHONGO_WRITERESULT_SCP("nMatched"); PHONGO_WRITERESULT_SCP("nModified"); PHONGO_WRITERESULT_SCP("nRemoved"); PHONGO_WRITERESULT_SCP("nUpserted"); #undef PHONGO_WRITERESULT_SCP if (bson_iter_init_find(&iter, intern->reply, "upserted") && BSON_ITER_HOLDS_ARRAY(&iter)) { uint32_t len; const uint8_t *data; 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; bson_iter_array(&iter, &len, &data); php_phongo_bson_to_zval_ex(data, 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 } else { #if PHP_VERSION_ID >= 70000 zval upsertedIds; array_init(&upsertedIds); ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", &upsertedIds); #else zval *upsertedIds = NULL; MAKE_STD_ZVAL(upsertedIds); array_init(upsertedIds); ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", upsertedIds); #endif } { #if PHP_VERSION_ID >= 70000 zval writeerrors; php_phongo_writeresult_get_writeerrors(intern, &writeerrors TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", &writeerrors); #else zval *writeerrors = NULL; MAKE_STD_ZVAL(writeerrors); php_phongo_writeresult_get_writeerrors(intern, writeerrors TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", writeerrors); #endif } { #if PHP_VERSION_ID >= 70000 zval writeconcernerror; php_phongo_writeresult_get_writeconcernerror(intern, &writeconcernerror TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "writeConcernError", &writeconcernerror); #else zval *writeconcernerror = NULL; MAKE_STD_ZVAL(writeconcernerror); php_phongo_writeresult_get_writeconcernerror(intern, writeconcernerror TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "writeConcernError", writeconcernerror); #endif } if (intern->write_concern) { #if PHP_VERSION_ID >= 70000 zval write_concern; phongo_writeconcern_init(&write_concern, intern->write_concern); ADD_ASSOC_ZVAL_EX(&retval, "writeConcern", &write_concern); #else zval *write_concern = NULL; MAKE_STD_ZVAL(write_concern); phongo_writeconcern_init(write_concern, intern->write_concern TSRMLS_CC); ADD_ASSOC_ZVAL_EX(&retval, "writeConcern", write_concern); #endif } else { ADD_ASSOC_NULL_EX(&retval, "writeConcern"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ void php_phongo_writeresult_init_ce(INIT_FUNC_ARGS) /* {{{ */ { zend_class_entry ce; 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_FINAL(php_phongo_writeresult_ce); PHONGO_CE_DISABLE_SERIALIZATION(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 } /* }}} */ /* * 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.3.4/src/contrib/php_array_api.h0000664000175000017500000005076513210321137020230 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; } switch (Z_TYPE_P(z)) { case IS_NULL: return (char *)""; case IS_STRING: *plen = Z_STRLEN_P(z); return Z_STRVAL_P(z); default: { zval c = *z; zval_copy_ctor(&c); convert_to_string(&c); #ifdef ZEND_ENGINE_3 *pfree = ! IS_INTERNED(Z_STR(c)); #else *pfree = ! IS_INTERNED(Z_STRVAL(c)); #endif *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.3.4/src/libbson/build/autotools/m4/ac_check_typedef.m40000664000175000017500000000264013210321137024370 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.3.4/src/libbson/build/autotools/m4/ac_compile_check_sizeof.m40000664000175000017500000000156613210321137025745 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.3.4/src/libbson/build/autotools/m4/ac_create_stdint_h.m40000664000175000017500000003662213210321137024741 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.3.4/src/libbson/build/autotools/m4/ax_check_compile_flag.m40000664000175000017500000000625113210321137025400 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.3.4/src/libbson/build/autotools/m4/ax_check_link_flag.m40000664000175000017500000000576013210321137024711 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.3.4/src/libbson/build/autotools/m4/ax_pthread.m40000664000175000017500000003303013210321137023244 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*) if test "$c_compiler" != "clang"; then ax_pthread_flags="-pthread $ax_pthread_flags" fi ;; 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.3.4/src/libbson/build/autotools/m4/pkg.m40000664000175000017500000001623113210321137021712 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.3.4/src/libbson/build/autotools/m4/silent.m40000664000175000017500000000267213210321137022433 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.3.4/src/libbson/build/autotools/CheckAtomics.m40000664000175000017500000000211213210321137023137 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.3.4/src/libbson/build/autotools/CheckCompiler.m40000664000175000017500000000432113210321137023316 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"], []) # If our BEGIN_IGNORE_DEPRECATIONS macro won't work, pass # -Wno-deprecated-declarations AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #if !defined(__clang__) && defined(__GNUC__) #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #if GCC_VERSION < 40600 #error Does not support deprecation warning pragmas #endif #endif ])], [], [CFLAGS="$CFLAGS -Wno-deprecated-declarations"]) 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.3.4/src/libbson/build/autotools/CheckHeaders.m40000664000175000017500000000033213210321137023115 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]) AC_CHECK_HEADERS_ONCE([strings.h]) mongodb-1.3.4/src/libbson/build/autotools/CheckHost.m40000664000175000017500000000135513210321137022465 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.3.4/src/libbson/build/autotools/CheckProgs.m40000664000175000017500000000062613210321137022642 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(SPHINX_BUILD, sphinx-build) AC_PROG_INSTALL mongodb-1.3.4/src/libbson/build/autotools/CheckTarget.m40000664000175000017500000000114713210321137022775 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.3.4/src/libbson/build/autotools/Coverage.m40000664000175000017500000000032013210321137022334 0ustar jmikolajmikolaCOVERAGE_CFLAGS="" COVERAGE_LDFLAGS="" if test "$enable_coverage" = "yes"; then COVERAGE_CFLAGS="--coverage -g" COVERAGE_LDFLAGS="--coverage" fi AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_LDFLAGS) mongodb-1.3.4/src/libbson/build/autotools/Endian.m40000664000175000017500000000026013210321137022002 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.3.4/src/libbson/build/autotools/FindDependencies.m40000664000175000017500000000731613210321137024004 0ustar jmikolajmikola# Check for strnlen() dnl AC_CHECK_FUNC isn't properly respecting _XOPEN_SOURCE for strnlen for unknown reason AC_SUBST(BSON_HAVE_STRNLEN, 0) AC_CACHE_CHECK([for strnlen], bson_cv_have_strnlen, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include int strnlen () { return 0; } ]])], [bson_cv_have_strnlen=no], [bson_cv_have_strnlen=yes])]) if test "$bson_cv_have_strnlen" = yes; then AC_SUBST(BSON_HAVE_STRNLEN, 1) fi # Check for reallocf() (BSD/Darwin) AC_SUBST(BSON_HAVE_REALLOCF, 0) AC_CACHE_CHECK([for reallocf], bson_cv_have_reallocf, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include int reallocf () { return 0; } ]])], [bson_cv_have_reallocf=no], [bson_cv_have_reallocf=yes])]) if test "$bson_cv_have_reallocf" = yes; then AC_SUBST(BSON_HAVE_REALLOCF, 1) fi # Check for syscall() AC_SUBST(BSON_HAVE_SYSCALL_TID, 0) AC_CACHE_CHECK([for syscall], bson_cv_have_syscall_tid, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include int syscall () { return 0; } ]])], [bson_cv_have_syscall_tid=no], [bson_cv_have_syscall_tid=yes])]) if test "$bson_cv_have_syscall_tid" = yes -a "$os_darwin" != "yes"; then AC_CACHE_CHECK([for SYS_gettid], bson_cv_have_sys_gettid_tid, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include int gettid () { return SYS_gettid; } ]])], [bson_cv_have_sys_gettid_tid=yes], [bson_cv_have_sys_gettid_tid=no])]) if test "$bson_cv_have_sys_gettid_tid" = yes; then AC_SUBST(BSON_HAVE_SYSCALL_TID, 1) fi fi # Check for snprintf() AC_SUBST(BSON_HAVE_SNPRINTF, 0) AC_CHECK_FUNC(snprintf, [AC_SUBST(BSON_HAVE_SNPRINTF, 1)]) # Check for struct timespec AC_SUBST(BSON_HAVE_TIMESPEC, 0) AC_CHECK_TYPE([struct timespec], [AC_SUBST(BSON_HAVE_TIMESPEC, 1)], [], [#include ]) # 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 if math functions need -lm AC_SEARCH_LIBS([floor], [m]) # Check for gmtime_r() AC_SUBST(BSON_HAVE_GMTIME_R, 0) AC_CHECK_FUNC(gmtime_r, [AC_SUBST(BSON_HAVE_GMTIME_R, 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.3.4/src/libbson/build/autotools/MaintainerFlags.m40000664000175000017500000000144013210321137023651 0ustar jmikolajmikolaAS_IF( [test "x$enable_maintainer_flags" = "xyes" && test "x$GCC" = "xyes"], [ # clang only warns if it doesn't support a warning option, turn it into an # error so we really know if whether it supports it. AX_CHECK_COMPILE_FLAG( "-Werror=unknown-warning-option", [WERROR_UNKNOWN_OPTION="-Werror=unknown-warning-option"], [WERROR_UNKNOWN_OPTION=""]) # Read maintainer-flags.txt and apply each flag that the compiler supports. m4_foreach([MAINTAINER_FLAG], m4_split(m4_normalize(m4_esyscmd(cat build/maintainer-flags.txt))), [ AX_CHECK_COMPILE_FLAG( MAINTAINER_FLAG, [MAINTAINER_CFLAGS="$MAINTAINER_CFLAGS MAINTAINER_FLAG"], [], [$WERROR_UNKNOWN_OPTION]) ]) ] AC_SUBST(MAINTAINER_CFLAGS) ) mongodb-1.3.4/src/libbson/build/autotools/Optimizations.m40000664000175000017500000000163213210321137023461 0ustar jmikolajmikolaOPTIMIZE_CFLAGS="" OPTIMIZE_LDFLAGS="" AC_DEFUN([check_link_flag], [AX_CHECK_LINK_FLAG([$1], [$2], [$3], [-Werror $4])]) # Enable -Bsymbolic AS_IF([test "$enable_optimizations" != "no"], [ check_link_flag([-Wl,-Bsymbolic], [OPTIMIZE_LDFLAGS="$OPTIMIZE_LDFLAGS -Wl,-Bsymbolic"]) CFLAGS="$CFLAGS -O2" ]) # Enable Link-Time-Optimization AS_IF([test "$enable_lto" = "yes"], [AS_IF([test "$c_compiler" = "gcc"], [AX_CHECK_COMPILE_FLAG([-flto], [OPTIMIZE_CFLAGS="$OPTIMIZE_CFLAGS -flto"]) check_link_flag([-flto], [OPTIMIZE_LDFLAGS="$OPTIMIZE_LDFLAGS -flto"])], [AC_MSG_WARN([LTO is not yet available on your compiler.])])]) 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 mongodb-1.3.4/src/libbson/build/autotools/PrintBuildConfiguration.m40000664000175000017500000000234113210321137025412 0ustar jmikolajmikolaAC_OUTPUT if test -n "$BSON_PRERELEASE_VERSION"; then cat << EOF *** IMPORTANT *** This is an unstable version of libbson. 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 libbson team. *** END OF WARNING *** EOF fi echo " libbson $BSON_VERSION was configured with the following options: Build configuration: Enable debugging (slow) : ${enable_debug} Enable extra alignment (required for 1.0 ABI) : ${enable_extra_align} Compile with debug symbols (slow) : ${enable_debug_symbols} Enable GCC build optimization : ${enable_optimizations} Code coverage support : ${enable_coverage} Cross Compiling : ${enable_crosscompile} Big endian : ${enable_bigendian} Link Time Optimization (experimental) : ${enable_lto} Documentation: man : ${enable_man_pages} HTML : ${enable_html_docs} " mongodb-1.3.4/src/libbson/build/autotools/ReadCommandLineArguments.m40000664000175000017500000000652613210321137025467 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 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 extra alignment of types]) AC_ARG_ENABLE(extra_align, AC_HELP_STRING([--enable-extra-align], [turn on extra alignment of types. This is required for the 1.0 ABI [default=yes]]), [enable_extra_align=$enableval], [enable_extra_align="yes"]) AC_MSG_RESULT([$enable_extra_align]) AS_IF([test "$enable_extra_align" = "yes"], [AC_SUBST(BSON_EXTRA_ALIGN, 1)], [AC_SUBST(BSON_EXTRA_ALIGN, 0)]) AC_ARG_ENABLE(lto, AC_HELP_STRING([--enable-lto], [turn on link time optimizations [default=no]]), [enable_lto=$enableval], [enable_lto=no]) 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]) # use strict compiler flags only on development releases m4_define([maintainer_flags_default], [m4_ifset([BSON_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]) 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([examples], [AS_HELP_STRING([--enable-examples=@<:@yes/no@:>@], [Build libbson examples.])], [], [enable_examples=yes]) AC_ARG_ENABLE([tests], [AS_HELP_STRING([--enable-tests=@<:@yes/no@:>@], [Build libbson tests.])], [], [enable_tests=yes]) mongodb-1.3.4/src/libbson/build/autotools/SetupAutomake.m40000664000175000017500000000322713210321137023401 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"]) AM_CONDITIONAL([ENABLE_STATIC],[test "$enable_static" = "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 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"]) AS_IF([test "$enable_man_pages" = "yes" && test -z "$SPHINX_BUILD"], [AC_MSG_ERROR([The Sphinx Python package must be installed to generate man pages.])]) # Should we build HTML documentation AM_CONDITIONAL([ENABLE_HTML_DOCS],[test "$enable_html_docs" = "yes"]) AS_IF([test "$enable_html_docs" = "yes" && test -z "$SPHINX_BUILD"], [AC_MSG_ERROR([The Sphinx Python package must be installed to generate HTML documentation.])]) mongodb-1.3.4/src/libbson/build/autotools/SetupLibtool.m40000664000175000017500000000011113210321137023224 0ustar jmikolajmikolaLT_PREREQ([2.2]) AC_DISABLE_STATIC AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL mongodb-1.3.4/src/libbson/build/autotools/Versions.m40000664000175000017500000000335213210321137022421 0ustar jmikolajmikolaBSON_CURRENT_FILE=${srcdir}/VERSION_CURRENT BSON_VERSION=$(cat $BSON_CURRENT_FILE) # Ensure newline for "cut" implementations that need it, e.g. HP-UX. BSON_MAJOR_VERSION=$( (cat $BSON_CURRENT_FILE; echo) | cut -d- -f1 | cut -d. -f1 ) BSON_MINOR_VERSION=$( (cat $BSON_CURRENT_FILE; echo) | cut -d- -f1 | cut -d. -f2 ) BSON_MICRO_VERSION=$( (cat $BSON_CURRENT_FILE; echo) | cut -d- -f1 | 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.3.4/src/libbson/src/bson/b64_ntop.h0000664000175000017500000001650713210321137020561 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.3.4/src/libbson/src/bson/b64_pton.h0000664000175000017500000003006613210321137020555 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.3.4/src/libbson/src/bson/bcon.c0000664000175000017500000006462313210321137020044 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" #include "bson-config.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 { \ BSON_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 { \ BSON_ASSERT (ctx->n < (BCON_STACK_MAX - 1)); \ ctx->n++; \ STACK_IS_ARRAY = 0; \ statement; \ } while (0) #define STACK_POP_ARRAY(statement) \ do { \ BSON_ASSERT (STACK_IS_ARRAY); \ BSON_ASSERT (ctx->n != 0); \ statement; \ ctx->n--; \ } while (0) #define STACK_POP_DOC(statement) \ do { \ BSON_ASSERT (!STACK_IS_ARRAY); \ BSON_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; bson_decimal128_t *DECIMAL128; 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; bson_decimal128_t *DECIMAL128; } 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_DECIMAL128: bson_append_decimal128 (bson, key, -1, val->DECIMAL128); 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: BSON_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_DECIMAL128: CHECK_TYPE (BSON_TYPE_DECIMAL128); bson_iter_decimal128 (iter, val->DECIMAL128); 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: BSON_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 *); BSON_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_DECIMAL128: u->DECIMAL128 = va_arg (*ap, bson_decimal128_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: BSON_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 *); BSON_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_DECIMAL128: u->DECIMAL128 = va_arg (*ap, bson_decimal128_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: BSON_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; } BSON_ASSERT (type == BCON_TYPE_UTF8); key = u.UTF8; } type = _bcon_append_tokenize (ap, &u); BSON_ASSERT (type != BCON_TYPE_END); switch ((int) type) { case BCON_TYPE_BCON: BSON_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; } BSON_ASSERT (type == BCON_TYPE_RAW); key = u.key; } type = _bcon_extract_tokenize (ap, &u); BSON_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.3.4/src/libbson/src/bson/bcon.h0000664000175000017500000002527313210321137020047 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.h" 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 (const_decimal128_ptr, const bson_decimal128_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_DECIMAL128(_val) \ BCON_MAGIC, BCON_TYPE_DECIMAL128, BCON_ENSURE (const_decimal128_ptr, (_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_DECIMAL128(_val) \ BCONE_MAGIC, BCON_TYPE_DECIMAL128, \ BCON_ENSURE_STORAGE (const_decimal128_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_DECIMAL128, 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; BSON_EXPORT (void) bcon_append (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED; BSON_EXPORT (void) bcon_append_ctx (bson_t *bson, bcon_append_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; BSON_EXPORT (void) bcon_append_ctx_va (bson_t *bson, bcon_append_ctx_t *ctx, va_list *va); BSON_EXPORT (void) bcon_append_ctx_init (bcon_append_ctx_t *ctx); BSON_EXPORT (void) bcon_extract_ctx_init (bcon_extract_ctx_t *ctx); BSON_EXPORT (void) bcon_extract_ctx (bson_t *bson, bcon_extract_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; BSON_EXPORT (bool) bcon_extract_ctx_va (bson_t *bson, bcon_extract_ctx_t *ctx, va_list *ap); BSON_EXPORT (bool) bcon_extract (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED; BSON_EXPORT (bool) bcon_extract_va (bson_t *bson, bcon_extract_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; BSON_EXPORT (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) BSON_EXPORT (const char *) bson_bcon_magic (void) BSON_GNUC_CONST; BSON_EXPORT (const char *) bson_bcone_magic (void) BSON_GNUC_CONST; BSON_END_DECLS #endif mongodb-1.3.4/src/libbson/src/bson/bson-atomic.c0000664000175000017500000000322513210321137021325 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 #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.3.4/src/libbson/src/bson/bson-atomic.h0000664000175000017500000000542413210321137021335 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 BSON_EXPORT (int32_t) bson_atomic_int_add (volatile int32_t *p, int32_t n); #endif #ifdef __BSON_NEED_ATOMIC_64 BSON_EXPORT (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." BSON_EXPORT (void) bson_memory_barrier (void); #endif BSON_END_DECLS #endif /* BSON_ATOMIC_H */ mongodb-1.3.4/src/libbson/src/bson/bson-clock.c0000664000175000017500000000744013210321137021147 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); #elif defined(__hpux__) int64_t nanosec = gethrtime (); return (nanosec / 1000UL); #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.3.4/src/libbson/src/bson/bson-clock.h0000664000175000017500000000175713210321137021161 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 BSON_EXPORT (int64_t) bson_get_monotonic_time (void); BSON_EXPORT (int) bson_gettimeofday (struct timeval *tv); BSON_END_DECLS #endif /* BSON_CLOCK_H */ mongodb-1.3.4/src/libbson/src/bson/bson-compat.h0000664000175000017500000000703113210321137021340 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 #include BSON_BEGIN_DECLS #ifdef _MSC_VER #include #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 #ifndef _SIZE_T_DEFINED #define _SIZE_T_DEFINED typedef SIZE_T size_t; #endif #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(__va_copy) #define va_copy(dst, src) __va_copy (dst, src) #endif #if !defined(va_copy) #define va_copy(dst, src) ((dst) = (src)) #endif BSON_END_DECLS #endif /* BSON_COMPAT_H */ mongodb-1.3.4/src/libbson/src/bson/bson-config.h0000664000175000017500000000477013210321137021331 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 gmtime_r available on your platform. */ #define BSON_HAVE_GMTIME_R 1 #if BSON_HAVE_GMTIME_R != 1 # undef BSON_HAVE_GMTIME_R #endif /* * Define to 1 if you have reallocf available on your platform. */ #define BSON_HAVE_REALLOCF 0 #if BSON_HAVE_REALLOCF != 1 # undef BSON_HAVE_REALLOCF #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 /* * Define to 1 if you have SYS_gettid syscall */ #define BSON_HAVE_SYSCALL_TID 1 #if BSON_HAVE_SYSCALL_TID != 1 # undef BSON_HAVE_SYSCALL_TID #endif #endif /* BSON_CONFIG_H */ mongodb-1.3.4/src/libbson/src/bson/bson-config.h.in0000664000175000017500000000544613210321137021737 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 gmtime_r available on your platform. */ #define BSON_HAVE_GMTIME_R @BSON_HAVE_GMTIME_R@ #if BSON_HAVE_GMTIME_R != 1 # undef BSON_HAVE_GMTIME_R #endif /* * Define to 1 if you have reallocf available on your platform. */ #define BSON_HAVE_REALLOCF @BSON_HAVE_REALLOCF@ #if BSON_HAVE_REALLOCF != 1 # undef BSON_HAVE_REALLOCF #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 /* * Define to 1 if you have SYS_gettid syscall */ #define BSON_HAVE_SYSCALL_TID @BSON_HAVE_SYSCALL_TID@ #if BSON_HAVE_SYSCALL_TID != 1 # undef BSON_HAVE_SYSCALL_TID #endif #endif /* BSON_CONFIG_H */ mongodb-1.3.4/src/libbson/src/bson/bson-context-private.h0000664000175000017500000000232113210321137023206 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.3.4/src/libbson/src/bson/bson-context.c0000664000175000017500000003040013210321137021530 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 #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" #ifdef BSON_HAVE_SYSCALL_TID #include #endif #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 256 #endif /* * Globals. */ static bson_context_t gContextDefault; #ifdef BSON_HAVE_SYSCALL_TID 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; #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ defined(__OpenBSD__) arc4random_buf (&context->seq32, sizeof (context->seq32)); context->seq32 &= 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 { #ifdef BSON_HAVE_SYSCALL_TID if ((flags & BSON_CONTEXT_USE_TASK_ID)) { int32_t tid; /* This call is always successful */ tid = gettid (); pid = BSON_UINT16_TO_BE (tid); } else #endif { pid = BSON_UINT16_TO_BE (_bson_getpid ()); } 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.3.4/src/libbson/src/bson/bson-context.h0000664000175000017500000000211513210321137021537 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_EXPORT (bson_context_t *) bson_context_new (bson_context_flags_t flags); BSON_EXPORT (void) bson_context_destroy (bson_context_t *context); BSON_EXPORT (bson_context_t *) bson_context_get_default (void) BSON_GNUC_CONST; BSON_END_DECLS #endif /* BSON_CONTEXT_H */ mongodb-1.3.4/src/libbson/src/bson/bson-decimal128.c0000664000175000017500000005320613210321137021706 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 #include #include #include "bson-decimal128.h" #include "bson-types.h" #include "bson-macros.h" #include "bson-string.h" #define BSON_DECIMAL128_EXPONENT_MAX 6111 #define BSON_DECIMAL128_EXPONENT_MIN -6176 #define BSON_DECIMAL128_EXPONENT_BIAS 6176 #define BSON_DECIMAL128_MAX_DIGITS 34 #define BSON_DECIMAL128_SET_NAN(dec) \ do { \ (dec).high = 0x7c00000000000000ull; \ (dec).low = 0; \ } while (0); #define BSON_DECIMAL128_SET_INF(dec, isneg) \ do { \ (dec).high = 0x7800000000000000ull + 0x8000000000000000ull * (isneg); \ (dec).low = 0; \ } while (0); /** * _bson_uint128_t: * * This struct represents a 128 bit integer. */ typedef struct { uint32_t parts[4]; /* 32-bit words stored high to low. */ } _bson_uint128_t; /** *------------------------------------------------------------------------------ * * _bson_uint128_divide1B -- * * This function divides a #_bson_uint128_t by 1000000000 (1 billion) and * computes the quotient and remainder. * * The remainder will contain 9 decimal digits for conversion to string. * * @value The #_bson_uint128_t operand. * @quotient A pointer to store the #_bson_uint128_t quotient. * @rem A pointer to store the #uint64_t remainder. * * Returns: * The quotient at @quotient and the remainder at @rem. * * Side effects: * None. * *------------------------------------------------------------------------------ */ static void _bson_uint128_divide1B (_bson_uint128_t value, /* IN */ _bson_uint128_t *quotient, /* OUT */ uint32_t *rem) /* OUT */ { const uint32_t DIVISOR = 1000 * 1000 * 1000; uint64_t _rem = 0; int i = 0; if (!value.parts[0] && !value.parts[1] && !value.parts[2] && !value.parts[3]) { *quotient = value; *rem = 0; return; } for (i = 0; i <= 3; i++) { _rem <<= 32; /* Adjust remainder to match value of next dividend */ _rem += value.parts[i]; /* Add the divided to _rem */ value.parts[i] = (uint32_t) (_rem / DIVISOR); _rem %= DIVISOR; /* Store the remainder */ } *quotient = value; *rem = (uint32_t) _rem; } /** *------------------------------------------------------------------------------ * * bson_decimal128_to_string -- * * This function converts a BID formatted decimal128 value to string, * accepting a &bson_decimal128_t as @dec. The string is stored at @str. * * @dec : The BID formatted decimal to convert. * @str : The output decimal128 string. At least %BSON_DECIMAL128_STRING *characters. * * Returns: * None. * * Side effects: * None. * *------------------------------------------------------------------------------ */ void bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */ char *str) /* OUT */ { uint32_t COMBINATION_MASK = 0x1f; /* Extract least significant 5 bits */ uint32_t EXPONENT_MASK = 0x3fff; /* Extract least significant 14 bits */ uint32_t COMBINATION_INFINITY = 30; /* Value of combination field for Inf */ uint32_t COMBINATION_NAN = 31; /* Value of combination field for NaN */ uint32_t EXPONENT_BIAS = 6176; /* decimal128 exponent bias */ char *str_out = str; /* output pointer in string */ char significand_str[35]; /* decoded significand digits */ /* Note: bits in this routine are referred to starting at 0, */ /* from the sign bit, towards the coefficient. */ uint32_t high; /* bits 0 - 31 */ uint32_t midh; /* bits 32 - 63 */ uint32_t midl; /* bits 64 - 95 */ uint32_t low; /* bits 96 - 127 */ uint32_t combination; /* bits 1 - 5 */ uint32_t biased_exponent; /* decoded biased exponent (14 bits) */ uint32_t significand_digits = 0; /* the number of significand digits */ uint32_t significand[36] = {0}; /* the base-10 digits in the significand */ uint32_t *significand_read = significand; /* read pointer into significand */ int32_t exponent; /* unbiased exponent */ int32_t scientific_exponent; /* the exponent if scientific notation is * used */ bool is_zero = false; /* true if the number is zero */ uint8_t significand_msb; /* the most signifcant significand bits (50-46) */ _bson_uint128_t significand128; /* temporary storage for significand decoding */ size_t i; /* indexing variables */ int j, k; memset (significand_str, 0, sizeof (significand_str)); if ((int64_t) dec->high < 0) { /* negative */ *(str_out++) = '-'; } low = (uint32_t) dec->low, midl = (uint32_t) (dec->low >> 32), midh = (uint32_t) dec->high, high = (uint32_t) (dec->high >> 32); /* Decode combination field and exponent */ combination = (high >> 26) & COMBINATION_MASK; if (BSON_UNLIKELY ((combination >> 3) == 3)) { /* Check for 'special' values */ if (combination == COMBINATION_INFINITY) { /* Infinity */ strcpy (str_out, BSON_DECIMAL128_INF); return; } else if (combination == COMBINATION_NAN) { /* NaN */ /* str, not str_out, to erase the sign */ strcpy (str, BSON_DECIMAL128_NAN); /* we don't care about the NaN payload. */ return; } else { biased_exponent = (high >> 15) & EXPONENT_MASK; significand_msb = 0x8 + ((high >> 14) & 0x1); } } else { significand_msb = (high >> 14) & 0x7; biased_exponent = (high >> 17) & EXPONENT_MASK; } exponent = biased_exponent - EXPONENT_BIAS; /* Create string of significand digits */ /* Convert the 114-bit binary number represented by */ /* (high, midh, midl, low) to at most 34 decimal */ /* digits through modulo and division. */ significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14); significand128.parts[1] = midh; significand128.parts[2] = midl; significand128.parts[3] = low; if (significand128.parts[0] == 0 && significand128.parts[1] == 0 && significand128.parts[2] == 0 && significand128.parts[3] == 0) { is_zero = true; } else if (significand128.parts[0] >= (1 << 17)) { /* The significand is non-canonical or zero. * In order to preserve compatability with the densely packed decimal * format, the maximum value for the significand of decimal128 is * 1e34 - 1. If the value is greater than 1e34 - 1, the IEEE 754 * standard dictates that the significand is interpreted as zero. */ is_zero = true; } else { for (k = 3; k >= 0; k--) { uint32_t least_digits = 0; _bson_uint128_divide1B ( significand128, &significand128, &least_digits); /* We now have the 9 least significant digits (in base 2). */ /* Convert and output to string. */ if (!least_digits) { continue; } for (j = 8; j >= 0; j--) { significand[k * 9 + j] = least_digits % 10; least_digits /= 10; } } } /* Output format options: */ /* Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd */ /* Regular - ddd.ddd */ if (is_zero) { significand_digits = 1; *significand_read = 0; } else { significand_digits = 36; while (!(*significand_read)) { significand_digits--; significand_read++; } } scientific_exponent = significand_digits - 1 + exponent; /* The scientific exponent checks are dictated by the string conversion * specification and are somewhat arbitrary cutoffs. * * We must check exponent > 0, because if this is the case, the number * has trailing zeros. However, we *cannot* output these trailing zeros, * because doing so would change the precision of the value, and would * change stored data if the string converted number is round tripped. */ if (scientific_exponent < -6 || exponent > 0) { /* Scientific format */ *(str_out++) = *(significand_read++) + '0'; significand_digits--; if (significand_digits) { *(str_out++) = '.'; } for (i = 0; i < significand_digits; i++) { *(str_out++) = *(significand_read++) + '0'; } /* Exponent */ *(str_out++) = 'E'; bson_snprintf (str_out, 6, "%+d", scientific_exponent); } else { /* Regular format with no decimal place */ if (exponent >= 0) { for (i = 0; i < significand_digits; i++) { *(str_out++) = *(significand_read++) + '0'; } *str_out = '\0'; } else { int32_t radix_position = significand_digits + exponent; if (radix_position > 0) { /* non-zero digits before radix */ for (i = 0; i < radix_position; i++) { *(str_out++) = *(significand_read++) + '0'; } } else { /* leading zero before radix point */ *(str_out++) = '0'; } *(str_out++) = '.'; while (radix_position++ < 0) { /* add leading zeros after radix */ *(str_out++) = '0'; } for (i = 0; i < significand_digits - BSON_MAX (radix_position - 1, 0); i++) { *(str_out++) = *(significand_read++) + '0'; } *str_out = '\0'; } } } typedef struct { uint64_t high, low; } _bson_uint128_6464_t; /** *------------------------------------------------------------------------- * * mul64x64 -- * * This function multiplies two &uint64_t into a &_bson_uint128_6464_t. * * Returns: * The product of @left and @right. * * Side Effects: * None. * *------------------------------------------------------------------------- */ static void _mul_64x64 (uint64_t left, /* IN */ uint64_t right, /* IN */ _bson_uint128_6464_t *product) /* OUT */ { uint64_t left_high, left_low, right_high, right_low, product_high, product_mid, product_mid2, product_low; _bson_uint128_6464_t rt = {0}; if (!left && !right) { *product = rt; return; } left_high = left >> 32; left_low = (uint32_t) left; right_high = right >> 32; right_low = (uint32_t) right; product_high = left_high * right_high; product_mid = left_high * right_low; product_mid2 = left_low * right_high; product_low = left_low * right_low; product_high += product_mid >> 32; product_mid = (uint32_t) product_mid + product_mid2 + (product_low >> 32); product_high = product_high + (product_mid >> 32); product_low = (product_mid << 32) + (uint32_t) product_low; rt.high = product_high; rt.low = product_low; *product = rt; } /** *------------------------------------------------------------------------------ * * _dec128_tolower -- * * This function converts the ASCII character @c to lowercase. It is locale * insensitive (unlike the stdlib tolower). * * Returns: * The lowercased character. */ char _dec128_tolower (char c) { if (isupper (c)) { c += 32; } return c; } /** *------------------------------------------------------------------------------ * * _dec128_istreq -- * * This function compares the null-terminated *ASCII* strings @a and @b * for case-insensitive equality. * * Returns: * true if the strings are equal, false otherwise. */ bool _dec128_istreq (const char *a, /* IN */ const char *b /* IN */) { while (*a != '\0' || *b != '\0') { /* strings are different lengths. */ if (*a == '\0' || *b == '\0') { return false; } if (_dec128_tolower (*a) != _dec128_tolower (*b)) { return false; } a++; b++; } return true; } /** *------------------------------------------------------------------------------ * * bson_decimal128_from_string -- * * This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to * decimal128. Out of range values are converted to +/-Infinity. Invalid * strings are converted to NaN. * * If more digits are provided than the available precision allows, * round to the nearest expressable decimal128 with ties going to even will * occur. * * Note: @string must be ASCII only! * * Returns: * true on success, or false on failure. @dec will be NaN if @str was invalid * The &bson_decimal128_t converted from @string at @dec. * * Side effects: * None. * *------------------------------------------------------------------------------ */ bool bson_decimal128_from_string (const char *string, /* IN */ bson_decimal128_t *dec) /* OUT */ { _bson_uint128_6464_t significand = {0}; const char *str_read = string; /* Read pointer for consuming str. */ /* Parsing state tracking */ bool is_negative = false; bool saw_radix = false; bool includes_sign = false; /* True if the input string contains a sign. */ bool found_nonzero = false; size_t significant_digits = 0; /* Total number of significant digits * (no leading or trailing zero) */ size_t ndigits_read = 0; /* Total number of significand digits read */ size_t ndigits = 0; /* Total number of digits (no leading zeros) */ size_t radix_position = 0; /* The number of the digits after radix */ size_t first_nonzero = 0; /* The index of the first non-zero in *str* */ uint16_t digits[BSON_DECIMAL128_MAX_DIGITS] = {0}; uint16_t ndigits_stored = 0; /* The number of digits in digits */ uint16_t *digits_insert = digits; /* Insertion pointer for digits */ size_t first_digit = 0; /* The index of the first non-zero digit */ size_t last_digit = 0; /* The index of the last digit */ int32_t exponent = 0; uint64_t significand_high = 0; /* The high 17 digits of the significand */ uint64_t significand_low = 0; /* The low 17 digits of the significand */ uint16_t biased_exponent = 0; /* The biased exponent */ BSON_ASSERT (dec); dec->high = 0; dec->low = 0; if (*str_read == '+' || *str_read == '-') { is_negative = *(str_read++) == '-'; includes_sign = true; } /* Check for Infinity or NaN */ if (!isdigit (*str_read) && *str_read != '.') { if (_dec128_istreq (str_read, "inf") || _dec128_istreq (str_read, "infinity")) { BSON_DECIMAL128_SET_INF (*dec, is_negative); return true; } else if (_dec128_istreq (str_read, "nan")) { BSON_DECIMAL128_SET_NAN (*dec); return true; } BSON_DECIMAL128_SET_NAN (*dec); return false; } /* Read digits */ while (isdigit (*str_read) || *str_read == '.') { if (*str_read == '.') { if (saw_radix) { BSON_DECIMAL128_SET_NAN (*dec); return false; } saw_radix = true; str_read++; continue; } if (ndigits_stored < 34) { if (*str_read != '0' || found_nonzero) { if (!found_nonzero) { first_nonzero = ndigits_read; } found_nonzero = true; *(digits_insert++) = *(str_read) - '0'; /* Only store 34 digits */ ndigits_stored++; } } if (found_nonzero) { ndigits++; } if (saw_radix) { radix_position++; } ndigits_read++; str_read++; } if (saw_radix && !ndigits_read) { BSON_DECIMAL128_SET_NAN (*dec); return false; } /* Read exponent if exists */ if (*str_read == 'e' || *str_read == 'E') { int nread = 0; #ifdef _MSC_VER #define SSCANF sscanf_s #else #define SSCANF sscanf #endif int read_exponent = SSCANF (++str_read, "%d%n", &exponent, &nread); str_read += nread; if (!read_exponent || nread == 0) { BSON_DECIMAL128_SET_NAN (*dec); return false; } #undef SSCANF } if (*str_read) { BSON_DECIMAL128_SET_NAN (*dec); return false; } /* Done reading input. */ /* Find first non-zero digit in digits */ first_digit = 0; if (!ndigits_stored) { /* value is zero */ first_digit = 0; last_digit = 0; digits[0] = 0; ndigits = 1; ndigits_stored = 1; significant_digits = 0; } else { last_digit = ndigits_stored - 1; significant_digits = ndigits; /* Mark trailing zeros as non-significant */ while (string[first_nonzero + significant_digits - 1 + includes_sign + saw_radix] == '0') { significant_digits--; } } /* Normalization of exponent */ /* Correct exponent based on radix position, and shift significand as needed */ /* to represent user input */ /* Overflow prevention */ if (exponent <= radix_position && radix_position - exponent > (1 << 14)) { exponent = BSON_DECIMAL128_EXPONENT_MIN; } else { exponent -= radix_position; } /* Attempt to normalize the exponent */ while (exponent > BSON_DECIMAL128_EXPONENT_MAX) { /* Shift exponent to significand and decrease */ last_digit++; if (last_digit - first_digit > BSON_DECIMAL128_MAX_DIGITS) { /* The exponent is too great to shift into the significand. */ if (significant_digits == 0) { /* Value is zero, we are allowed to clamp the exponent. */ exponent = BSON_DECIMAL128_EXPONENT_MAX; break; } /* Overflow is not permitted, error. */ BSON_DECIMAL128_SET_NAN (*dec); return false; } exponent--; } while (exponent < BSON_DECIMAL128_EXPONENT_MIN || ndigits_stored < ndigits) { /* Shift last digit */ if (last_digit == 0) { /* underflow is not allowed, but zero clamping is */ if (significant_digits == 0) { exponent = BSON_DECIMAL128_EXPONENT_MIN; break; } BSON_DECIMAL128_SET_NAN (*dec); return false; } if (ndigits_stored < ndigits) { if (string[ndigits - 1 + includes_sign + saw_radix] - '0' != 0 && significant_digits != 0) { BSON_DECIMAL128_SET_NAN (*dec); return false; } ndigits--; /* adjust to match digits not stored */ } else { if (digits[last_digit] != 0) { /* Inexact rounding is not allowed. */ BSON_DECIMAL128_SET_NAN (*dec); return false; } last_digit--; /* adjust to round */ } if (exponent < BSON_DECIMAL128_EXPONENT_MAX) { exponent++; } else { BSON_DECIMAL128_SET_NAN (*dec); return false; } } /* Round */ /* We've normalized the exponent, but might still need to round. */ if (last_digit - first_digit + 1 < significant_digits) { uint8_t round_digit; /* There are non-zero digits after last_digit that need rounding. */ /* We round to nearest, ties to even */ round_digit = string[first_nonzero + last_digit + includes_sign + saw_radix + 1] - '0'; if (round_digit != 0) { /* Inexact (non-zero) rounding is not allowed */ BSON_DECIMAL128_SET_NAN (*dec); return false; } } /* Encode significand */ significand_high = 0, /* The high 17 digits of the significand */ significand_low = 0; /* The low 17 digits of the significand */ if (significant_digits == 0) { /* read a zero */ significand_high = 0; significand_low = 0; } else if (last_digit - first_digit < 17) { size_t d_idx = first_digit; significand_low = digits[d_idx++]; for (; d_idx <= last_digit; d_idx++) { significand_low *= 10; significand_low += digits[d_idx]; significand_high = 0; } } else { size_t d_idx = first_digit; significand_high = digits[d_idx++]; for (; d_idx <= last_digit - 17; d_idx++) { significand_high *= 10; significand_high += digits[d_idx]; } significand_low = digits[d_idx++]; for (; d_idx <= last_digit; d_idx++) { significand_low *= 10; significand_low += digits[d_idx]; } } _mul_64x64 (significand_high, 100000000000000000ull, &significand); significand.low += significand_low; if (significand.low < significand_low) { significand.high += 1; } biased_exponent = (exponent + (int16_t) BSON_DECIMAL128_EXPONENT_BIAS); /* Encode combination, exponent, and significand. */ if ((significand.high >> 49) & 1) { /* Encode '11' into bits 1 to 3 */ dec->high |= (0x3ull << 61); dec->high |= (biased_exponent & 0x3fffull) << 47; dec->high |= significand.high & 0x7fffffffffffull; } else { dec->high |= (biased_exponent & 0x3fffull) << 49; dec->high |= significand.high & 0x1ffffffffffffull; } dec->low = significand.low; /* Encode sign */ if (is_negative) { dec->high |= 0x8000000000000000ull; } return true; } mongodb-1.3.4/src/libbson/src/bson/bson-decimal128.h0000664000175000017500000000271413210321137021711 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 BSON_DECIMAL128_H #define BSON_DECIMAL128_H #if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION) #error "Only can be included directly." #endif #include #include "bson-macros.h" #include "bson-config.h" #include "bson-types.h" /** * BSON_DECIMAL128_STRING: * * The length of a decimal128 string (with null terminator). * * 1 for the sign * 35 for digits and radix * 2 for exponent indicator and sign * 4 for exponent digits */ #define BSON_DECIMAL128_STRING 43 #define BSON_DECIMAL128_INF "Infinity" #define BSON_DECIMAL128_NAN "NaN" BSON_BEGIN_DECLS BSON_EXPORT (void) bson_decimal128_to_string (const bson_decimal128_t *dec, char *str); /* Note: @string must be ASCII characters only! */ BSON_EXPORT (bool) bson_decimal128_from_string (const char *string, bson_decimal128_t *dec); BSON_END_DECLS #endif /* BSON_DECIMAL128_H */ mongodb-1.3.4/src/libbson/src/bson/bson-endian.h0000664000175000017500000001447013210321137021320 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.3.4/src/libbson/src/bson/bson-error.c0000664000175000017500000000616613210321137021211 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(_WIN32) if (strerror_s (buf, buflen, err_code) != 0) { ret = buf; } #elif defined(__GNUC__) && defined(_GNU_SOURCE) ret = strerror_r (err_code, buf, buflen); #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.3.4/src/libbson/src/bson/bson-error.h0000664000175000017500000000217313210321137021210 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_INVALID 3 BSON_EXPORT (void) bson_set_error (bson_error_t *error, uint32_t domain, uint32_t code, const char *format, ...) BSON_GNUC_PRINTF (4, 5); BSON_EXPORT (char *) bson_strerror_r (int err_code, char *buf, size_t buflen); BSON_END_DECLS #endif /* BSON_ERROR_H */ mongodb-1.3.4/src/libbson/src/bson/bson-iso8601-private.h0000664000175000017500000000243413210321137022640 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" #include "bson-string.h" BSON_BEGIN_DECLS bool _bson_iso8601_date_parse (const char *str, int32_t len, int64_t *out, bson_error_t *error); /** * _bson_iso8601_date_format: * @msecs_since_epoch: A positive number of milliseconds since Jan 1, 1970. * @str: The string to append the ISO8601-formatted to. * * Appends a date formatted like "2012-12-24T12:15:30.500Z" to @str. */ void _bson_iso8601_date_format (int64_t msecs_since_epoch, bson_string_t *str); BSON_END_DECLS #endif /* BSON_ISO8601_PRIVATE_H */ mongodb-1.3.4/src/libbson/src/bson/bson-iso8601.c0000664000175000017500000002044713210321137021167 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" #include "bson-json.h" #include "bson-timegm-private.h" 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, bson_error_t *error) { 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; struct bson_tm posix_date = {0}; #define DATE_PARSE_ERR(msg) \ bson_set_error (error, \ BSON_ERROR_JSON, \ BSON_JSON_ERROR_READ_INVALID_PARAM, \ "Could not parse \"%s\" as date: " msg, \ str); \ return false #define DEFAULT_DATE_PARSE_ERR \ DATE_PARSE_ERR ("use ISO8601 format yyyy-mm-ddThh:mm plus timezone, either" \ " \"Z\" or like \"+0500\"") ptr = str; /* we have to match at least yyyy-mm-ddThh:mm */ 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))) { DEFAULT_DATE_PARSE_ERR; } /* if the minute has a ':' at the end look for seconds */ if (min_ptr[min_len] == ':') { if (remaining < 2) { DATE_PARSE_ERR ("reached end of date while looking for seconds"); } get_tok (".+-Z", &ptr, &remaining, &sec_ptr, &sec_len); if (!sec_len) { DATE_PARSE_ERR ("minute ends in \":\" seconds is required"); } } /* if we had a second and it is followed by a '.' look for milliseconds */ if (sec_len && sec_ptr[sec_len] == '.') { if (remaining < 2) { DATE_PARSE_ERR ("reached end of date while looking for milliseconds"); } get_tok ("+-Z", &ptr, &remaining, &millis_ptr, &millis_len); if (!millis_len) { DATE_PARSE_ERR ("seconds ends in \".\", milliseconds is required"); } } /* backtrack by 1 to put ptr on the timezone */ ptr--; remaining++; get_tok ("", &ptr, &remaining, &tz_ptr, &tz_len); if (!parse_num (year_ptr, year_len, 4, -9999, 9999, &year)) { DATE_PARSE_ERR ("year must be an integer"); } /* values are as in struct tm */ year -= 1900; if (!parse_num (month_ptr, month_len, 2, 1, 12, &month)) { DATE_PARSE_ERR ("month must be an integer"); } /* values are as in struct tm */ month -= 1; if (!parse_num (day_ptr, day_len, 2, 1, 31, &day)) { DATE_PARSE_ERR ("day must be an integer"); } if (!parse_num (hour_ptr, hour_len, 2, 0, 23, &hour)) { DATE_PARSE_ERR ("hour must be an integer"); } if (!parse_num (min_ptr, min_len, 2, 0, 59, &min)) { DATE_PARSE_ERR ("minute must be an integer"); } if (sec_len && !parse_num (sec_ptr, sec_len, 2, 0, 60, &sec)) { DATE_PARSE_ERR ("seconds must be an integer"); } 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)) { DATE_PARSE_ERR ("could not parse timezone"); } if (!parse_num (tz_ptr + 1, 2, -1, -23, 23, &tz_hour)) { DATE_PARSE_ERR ("timezone hour must be at most 23"); } if (!parse_num (tz_ptr + 3, 2, -1, 0, 59, &tz_min)) { DATE_PARSE_ERR ("timezone minute must be at most 59"); } /* 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)) { DATE_PARSE_ERR ("timezone offset must be less than 24 hours"); } } else { DATE_PARSE_ERR ("timezone is required"); } } if (millis_len > 0) { int i; int magnitude; millis = 0; if (millis_len > 3 || !digits_only (millis_ptr, millis_len)) { DATE_PARSE_ERR ("milliseconds must be an integer"); } 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) { DATE_PARSE_ERR ("milliseconds must be at least 0 and less than 1000"); } } 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 * _bson_timegm (&posix_date) + millis; millis += tz_adjustment * 1000; *out = millis; return true; } void _bson_iso8601_date_format (int64_t msec_since_epoch, bson_string_t *str) { time_t t; int64_t msecs_part; char buf[64]; msecs_part = msec_since_epoch % 1000; t = (time_t) (msec_since_epoch / 1000); #ifdef BSON_HAVE_GMTIME_R { struct tm posix_date; gmtime_r (&t, &posix_date); strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S", &posix_date); } #else { /* Windows gmtime is thread-safe */ strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S", gmtime (&t)); } #endif if (msecs_part) { bson_string_append_printf (str, "%s.%3" PRId64 "Z", buf, msecs_part); } else { bson_string_append (str, buf); bson_string_append_c (str, 'Z'); } } mongodb-1.3.4/src/libbson/src/bson/bson-iter.c0000664000175000017500000016335713210321137021031 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" #include "bson-config.h" #include "bson-decimal128.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_init_from_data -- * * Initializes @iter to be used to iterate @data of length @length * * Returns: * true if bson_iter_t was initialized. otherwise false. * * Side effects: * @iter is initialized. * *-------------------------------------------------------------------------- */ bool bson_iter_init_from_data (bson_iter_t *iter, /* OUT */ const uint8_t *data, /* IN */ size_t length) /* IN */ { uint32_t len_le; BSON_ASSERT (iter); BSON_ASSERT (data); if (BSON_UNLIKELY ((length < 5) || (length > INT_MAX))) { memset (iter, 0, sizeof *iter); return false; } memcpy (&len_le, data, sizeof (len_le)); if (BSON_UNLIKELY ((size_t) BSON_UINT32_FROM_LE (len_le) != length)) { memset (iter, 0, sizeof *iter); return false; } if (BSON_UNLIKELY (data[length - 1])) { memset (iter, 0, sizeof *iter); return false; } iter->raw = (uint8_t *) data; iter->len = length; 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)) { if (!bson_strcasecmp (key, bson_iter_key (iter))) { 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_internal -- * * Internal function to advance @iter to the next field and retrieve * the key and BSON type before error-checking. * * Return: * true if an element was decoded, else false. * * Side effects: * @key and @bson_type are set. * * If the return value is false: * - @iter is invalidated: @iter->raw is NULLed * - @unsupported is set to true if the bson type is unsupported * - otherwise if the BSON is corrupt, @iter->err_off is nonzero * - otherwise @bson_type is set to BSON_TYPE_EOD * *-------------------------------------------------------------------------- */ static bool _bson_iter_next_internal (bson_iter_t *iter, /* INOUT */ const char **key, /* OUT */ uint32_t *bson_type, /* OUT */ bool *unsupported) /* OUT */ { const uint8_t *data; uint32_t o; unsigned int len; BSON_ASSERT (iter); *unsupported = false; if (!iter->raw) { *key = NULL; *bson_type = BSON_TYPE_EOD; 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; /* iterate from start to end of NULL-terminated key string */ for (o = iter->off + 1; o < len; o++) { if (!data[o]) { iter->d1 = ++o; goto fill_data_fields; } } goto mark_invalid; fill_data_fields: *key = bson_iter_key_unsafe (iter); *bson_type = ITER_TYPE (iter); switch (*bson_type) { 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) { int32_t binary_len; if (l < 4) { iter->err_off = o; goto mark_invalid; } /* subtype 2 has a redundant length header in the data */ memcpy (&binary_len, (iter->raw + iter->d3), sizeof (binary_len)); binary_len = BSON_UINT32_FROM_LE (binary_len); if (binary_len + 4 != l) { iter->err_off = iter->d3; 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: { char val; if (iter->d1 >= len) { iter->err_off = o; goto mark_invalid; } memcpy (&val, iter->raw + iter->d1, 1); if (val != 0x00 && val != 0x01) { iter->err_off = o; goto mark_invalid; } 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; } if (*(iter->raw + o + l + 3)) { /* not null terminated */ iter->err_off = o + l + 3; 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 == 0 || 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_DECIMAL128: iter->next_off = o + 16; 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; default: *unsupported = true; /* FALL THROUGH */ case BSON_TYPE_EOD: 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_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 */ { uint32_t bson_type; const char *key; bool unsupported; return _bson_iter_next_internal (iter, &key, &bson_type, &unsupported); } /* *-------------------------------------------------------------------------- * * 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's bson_t is valid and unmodified. * * 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_as_double -- * * If @iter is on a field of type BSON_TYPE_DOUBLE, * returns the double. If it is on an integer field * such as int32, int64, or bool, it will convert * the value to a double. * * * Returns: * A double. * * Side effects: * None. * *-------------------------------------------------------------------------- */ double bson_iter_as_double (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); switch ((int) ITER_TYPE (iter)) { case BSON_TYPE_BOOL: return (double) bson_iter_bool (iter); case BSON_TYPE_DOUBLE: return bson_iter_double (iter); case BSON_TYPE_INT32: return (double) bson_iter_int32 (iter); case BSON_TYPE_INT64: return (double) bson_iter_int64 (iter); default: 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_decimal128 -- * * This function retrieves the current field of type *%BSON_TYPE_DECIMAL128. * The result is valid while @iter is valid, and is stored in @dec. * * Returns: * * True on success, false on failure. * * Side Effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_decimal128 (const bson_iter_t *iter, /* IN */ bson_decimal128_t *dec) /* OUT */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) { bson_iter_decimal128_unsafe (iter, dec); return true; } return false; } /* *-------------------------------------------------------------------------- * * 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)); /* The string length was checked > 0 in _bson_iter_next_internal. */ len = BSON_UINT32_FROM_LE (len); BSON_ASSERT (len > 0); *length = 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_DECIMAL128 VISIT_FIELD (decimal128) #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 */ { uint32_t bson_type; const char *key; bool unsupported; BSON_ASSERT (iter); BSON_ASSERT (visitor); while (_bson_iter_next_internal (iter, &key, &bson_type, &unsupported)) { if (*key && !bson_utf8_validate (key, strlen (key), false)) { iter->err_off = iter->off; break; } if (VISIT_BEFORE (iter, key, data)) { return true; } switch (bson_type) { 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 (!bson_utf8_validate (regex, strlen (regex), true)) { iter->err_off = iter->off; return true; } 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 (!bson_utf8_validate (collection, collection_len, true)) { iter->err_off = iter->off; return true; } 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 (!bson_utf8_validate (code, code_len, true)) { iter->err_off = iter->off; return true; } 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 (!bson_utf8_validate (symbol, symbol_len, true)) { iter->err_off = iter->off; return true; } 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_utf8_validate (code, length, true)) { iter->err_off = iter->off; return true; } 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_DECIMAL128: { bson_decimal128_t dec; bson_iter_decimal128 (iter, &dec); if (VISIT_DECIMAL128 (iter, key, &dec, 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) { if (unsupported && visitor->visit_unsupported_type && bson_utf8_validate (key, strlen (key), false)) { visitor->visit_unsupported_type (iter, key, bson_type, data); return false; } 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_overwrite_decimal128 -- * * Overwrites the current BSON_TYPE_DECIMAL128 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_decimal128 (bson_iter_t *iter, /* IN */ bson_decimal128_t *value) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) { #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN uint64_t data[2]; data[0] = BSON_UINT64_TO_LE (value->low); data[1] = BSON_UINT64_TO_LE (value->high); memcpy ((void *) (iter->raw + iter->d1), data, sizeof (data)); #else memcpy ((void *) (iter->raw + iter->d1), value, sizeof (*value)); #endif } } /* *-------------------------------------------------------------------------- * * 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_DECIMAL128: bson_iter_decimal128 (iter, &(value->value.v_decimal128)); 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.3.4/src/libbson/src/bson/bson-iter.h0000664000175000017500000002762713210321137021035 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_DECIMAL128(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_DECIMAL128) #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_HOLDS_INT(iter) \ (BSON_ITER_HOLDS_INT32 (iter) || BSON_ITER_HOLDS_INT64 (iter)) #define BSON_ITER_HOLDS_NUMBER(iter) \ (BSON_ITER_HOLDS_INT (iter) || BSON_ITER_HOLDS_DOUBLE (iter)) #define BSON_ITER_IS_KEY(iter, key) \ (0 == strcmp ((key), bson_iter_key ((iter)))) BSON_EXPORT (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); } BSON_EXPORT (void) bson_iter_array (const bson_iter_t *iter, uint32_t *array_len, const uint8_t **array); BSON_EXPORT (void) bson_iter_binary (const bson_iter_t *iter, bson_subtype_t *subtype, uint32_t *binary_len, const uint8_t **binary); BSON_EXPORT (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); } BSON_EXPORT (const char *) bson_iter_codewscope (const bson_iter_t *iter, uint32_t *length, uint32_t *scope_len, const uint8_t **scope); BSON_EXPORT (void) bson_iter_dbpointer (const bson_iter_t *iter, uint32_t *collection_len, const char **collection, const bson_oid_t **oid); BSON_EXPORT (void) bson_iter_document (const bson_iter_t *iter, uint32_t *document_len, const uint8_t **document); BSON_EXPORT (double) bson_iter_double (const bson_iter_t *iter); BSON_EXPORT (double) bson_iter_as_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); } BSON_EXPORT (bool) bson_iter_init (bson_iter_t *iter, const bson_t *bson); BSON_EXPORT (bool) bson_iter_init_from_data (bson_iter_t *iter, const uint8_t *data, size_t length); BSON_EXPORT (bool) bson_iter_init_find (bson_iter_t *iter, const bson_t *bson, const char *key); BSON_EXPORT (bool) bson_iter_init_find_case (bson_iter_t *iter, const bson_t *bson, const char *key); BSON_EXPORT (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); } BSON_EXPORT (int64_t) bson_iter_int64 (const bson_iter_t *iter); BSON_EXPORT (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); } BSON_EXPORT (bool) bson_iter_find (bson_iter_t *iter, const char *key); BSON_EXPORT (bool) bson_iter_find_case (bson_iter_t *iter, const char *key); BSON_EXPORT (bool) bson_iter_find_descendant (bson_iter_t *iter, const char *dotkey, bson_iter_t *descendant); BSON_EXPORT (bool) bson_iter_next (bson_iter_t *iter); BSON_EXPORT (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); } BSON_EXPORT (bool) bson_iter_decimal128 (const bson_iter_t *iter, bson_decimal128_t *dec); /** * bson_iter_decimal128_unsafe: * @iter: A #bson_iter_t. * * Similar to bson_iter_decimal128() but performs no integrity checks. * * Returns: A #bson_decimal128_t. */ static BSON_INLINE void bson_iter_decimal128_unsafe (const bson_iter_t *iter, bson_decimal128_t *dec) { uint64_t low_le; uint64_t high_le; memcpy (&low_le, iter->raw + iter->d1, sizeof (low_le)); memcpy (&high_le, iter->raw + iter->d1 + 8, sizeof (high_le)); dec->low = BSON_UINT64_FROM_LE (low_le); dec->high = BSON_UINT64_FROM_LE (high_le); } BSON_EXPORT (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); } BSON_EXPORT (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); } BSON_EXPORT (char *) bson_iter_dup_utf8 (const bson_iter_t *iter, uint32_t *length); BSON_EXPORT (int64_t) bson_iter_date_time (const bson_iter_t *iter); BSON_EXPORT (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); } BSON_EXPORT (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; } BSON_EXPORT (void) bson_iter_timestamp (const bson_iter_t *iter, uint32_t *timestamp, uint32_t *increment); BSON_EXPORT (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; } BSON_EXPORT (bool) bson_iter_as_bool (const bson_iter_t *iter); BSON_EXPORT (const char *) bson_iter_regex (const bson_iter_t *iter, const char **options); BSON_EXPORT (const char *) bson_iter_symbol (const bson_iter_t *iter, uint32_t *length); BSON_EXPORT (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]; } BSON_EXPORT (bool) bson_iter_recurse (const bson_iter_t *iter, bson_iter_t *child); BSON_EXPORT (void) bson_iter_overwrite_int32 (bson_iter_t *iter, int32_t value); BSON_EXPORT (void) bson_iter_overwrite_int64 (bson_iter_t *iter, int64_t value); BSON_EXPORT (void) bson_iter_overwrite_double (bson_iter_t *iter, double value); BSON_EXPORT (void) bson_iter_overwrite_decimal128 (bson_iter_t *iter, bson_decimal128_t *value); BSON_EXPORT (void) bson_iter_overwrite_bool (bson_iter_t *iter, bool value); BSON_EXPORT (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.3.4/src/libbson/src/bson/bson-json.c0000664000175000017500000022424613210321137021032 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 "jsonsl/jsonsl.h" #ifdef _WIN32 #include #include #endif #ifndef _MSC_VER #include #endif #ifdef _MSC_VER #define SSCANF sscanf_s #else #define SSCANF sscanf #endif #define STACK_MAX 100 #define BSON_JSON_DEFAULT_BUF_SIZE (1 << 14) #define AT_LEAST_0(x) ((x) >= 0 ? (x) : 0) #define READ_STATE_ENUM(ENUM) BSON_JSON_##ENUM, #define GENERATE_STRING(STRING) #STRING, #define FOREACH_READ_STATE(RS) \ RS (REGULAR) \ RS (DONE) \ RS (ERROR) \ RS (IN_START_MAP) \ RS (IN_BSON_TYPE) \ RS (IN_BSON_TYPE_DATE_NUMBERLONG) \ RS (IN_BSON_TYPE_DATE_ENDMAP) \ RS (IN_BSON_TYPE_TIMESTAMP_STARTMAP) \ RS (IN_BSON_TYPE_TIMESTAMP_VALUES) \ RS (IN_BSON_TYPE_TIMESTAMP_ENDMAP) \ RS (IN_BSON_TYPE_REGEX_STARTMAP) \ RS (IN_BSON_TYPE_REGEX_VALUES) \ RS (IN_BSON_TYPE_REGEX_ENDMAP) \ RS (IN_BSON_TYPE_BINARY_VALUES) \ RS (IN_BSON_TYPE_BINARY_ENDMAP) \ RS (IN_BSON_TYPE_SCOPE_STARTMAP) \ RS (IN_BSON_TYPE_DBPOINTER_STARTMAP) \ RS (IN_SCOPE) \ RS (IN_DBPOINTER) typedef enum { FOREACH_READ_STATE (READ_STATE_ENUM) } bson_json_read_state_t; static const char *read_state_names[] = {FOREACH_READ_STATE (GENERATE_STRING)}; #define BSON_STATE_ENUM(ENUM) BSON_JSON_LF_##ENUM, #define FOREACH_BSON_STATE(BS) \ /* legacy {$regex: "...", $options: "..."} */ \ BS (REGEX) \ BS (OPTIONS) \ /* modern $regularExpression: {pattern: "...", options: "..."} */ \ BS (REGULAR_EXPRESSION_PATTERN) \ BS (REGULAR_EXPRESSION_OPTIONS) \ BS (CODE) \ BS (SCOPE) \ BS (OID) \ BS (BINARY) \ BS (TYPE) \ BS (DATE) \ BS (TIMESTAMP_T) \ BS (TIMESTAMP_I) \ BS (UNDEFINED) \ BS (MINKEY) \ BS (MAXKEY) \ BS (INT32) \ BS (INT64) \ BS (DOUBLE) \ BS (DECIMAL128) \ BS (DBPOINTER) \ BS (SYMBOL) \ BS (DBREF) typedef enum { FOREACH_BSON_STATE (BSON_STATE_ENUM) } bson_json_read_bson_state_t; static const char *bson_state_names[] = {FOREACH_BSON_STATE (GENERATE_STRING)}; typedef struct { uint8_t *buf; size_t n_bytes; size_t len; } bson_json_buf_t; typedef enum { BSON_JSON_FRAME_ARRAY, BSON_JSON_FRAME_DOC, BSON_JSON_FRAME_SCOPE, BSON_JSON_FRAME_DBPOINTER, } bson_json_frame_type_t; typedef struct { int i; bson_json_frame_type_t type; bool has_ref; bool has_id; bson_t bson; } bson_json_stack_frame_t; typedef union { struct { bool has_pattern; bool has_options; bool is_legacy; } regex; struct { bool has_oid; bson_oid_t oid; } oid; struct { bool has_binary; bool has_subtype; bson_subtype_t type; bool is_legacy; } 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 { int32_t value; } v_int32; struct { int64_t value; } v_int64; struct { double value; } v_double; struct { bson_decimal128_t value; } v_decimal128; } bson_json_bson_data_t; /* collect info while parsing a {$code: "...", $scope: {...}} object */ typedef struct { bool has_code; bool has_scope; bool in_scope; bson_json_buf_t key_buf; bson_json_buf_t code_buf; } bson_json_code_t; static void _bson_json_code_cleanup (bson_json_code_t *code_data) { bson_free (code_data->key_buf.buf); bson_free (code_data->code_buf.buf); } 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_buf_t unescaped; 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; bson_json_code_t code_data; bson_json_buf_t dbpointer_key; } 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; jsonsl_t json; ssize_t json_text_pos; bool should_reset; ssize_t advance; bson_json_buf_t tok_accumulator; bson_error_t *error; }; typedef struct { int fd; bool do_close; } bson_json_reader_handle_fd_t; /* forward decl */ static void _bson_json_save_map_key (bson_json_reader_bson_t *bson, const uint8_t *val, size_t len); 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_FRAME_TYPE STACK_ELE (0, type) #define STACK_IS_ARRAY (STACK_FRAME_TYPE == BSON_JSON_FRAME_ARRAY) #define STACK_IS_DOC (STACK_FRAME_TYPE == BSON_JSON_FRAME_DOC) #define STACK_IS_SCOPE (STACK_FRAME_TYPE == BSON_JSON_FRAME_SCOPE) #define STACK_IS_DBPOINTER (STACK_FRAME_TYPE == BSON_JSON_FRAME_DBPOINTER) #define STACK_HAS_REF STACK_ELE (0, has_ref) #define STACK_HAS_ID STACK_ELE (0, has_id) #define STACK_PUSH_ARRAY(statement) \ do { \ if (bson->n >= (STACK_MAX - 1)) { \ return; \ } \ bson->n++; \ STACK_I = 0; \ STACK_FRAME_TYPE = BSON_JSON_FRAME_ARRAY; \ if (bson->n != 0) { \ statement; \ } \ } while (0) #define STACK_PUSH_DOC(statement) \ do { \ if (bson->n >= (STACK_MAX - 1)) { \ return; \ } \ bson->n++; \ STACK_FRAME_TYPE = BSON_JSON_FRAME_DOC; \ STACK_HAS_REF = false; \ STACK_HAS_ID = false; \ if (bson->n != 0) { \ statement; \ } \ } while (0) #define STACK_PUSH_SCOPE(statement) \ do { \ if (bson->n >= (STACK_MAX - 1)) { \ return; \ } \ bson->n++; \ STACK_FRAME_TYPE = BSON_JSON_FRAME_SCOPE; \ bson->code_data.in_scope = true; \ if (bson->n != 0) { \ statement; \ } \ } while (0) #define STACK_PUSH_DBPOINTER(statement) \ do { \ if (bson->n >= (STACK_MAX - 1)) { \ return; \ } \ bson->n++; \ STACK_FRAME_TYPE = BSON_JSON_FRAME_DBPOINTER; \ if (bson->n != 0) { \ statement; \ } \ } while (0) #define STACK_POP_ARRAY(statement) \ do { \ if (!STACK_IS_ARRAY) { \ return; \ } \ if (bson->n < 0) { \ return; \ } \ if (bson->n > 0) { \ statement; \ } \ bson->n--; \ } while (0) #define STACK_POP_DOC(statement) \ do { \ if (STACK_IS_ARRAY) { \ return; \ } \ if (bson->n < 0) { \ return; \ } \ if (bson->n > 0) { \ statement; \ } \ bson->n--; \ } while (0) #define STACK_POP_SCOPE \ do { \ STACK_POP_DOC (_noop ()); \ bson->code_data.in_scope = false; \ } while (0); #define STACK_POP_DBPOINTER STACK_POP_DOC (_noop ()) #define BASIC_CB_PREAMBLE \ const char *key; \ size_t len; \ bson_json_reader_bson_t *bson = &reader->bson; \ _bson_json_read_fixup_key (bson); \ key = bson->key; \ len = bson->key_buf.len; #define BASIC_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 %s", \ (_type), \ read_state_names[bson->read_state]); \ return; \ } else if (!key) { \ _bson_json_read_set_error (reader, \ "Invalid read of %s without key in state %s", \ (_type), \ read_state_names[bson->read_state]); \ return; \ } #define HANDLE_OPTION(_key, _type, _state) \ (len == strlen (_key) && strncmp ((const char *) val, (_key), len) == 0) \ { \ if (bson->bson_type && bson->bson_type != (_type)) { \ _bson_json_read_set_error (reader, \ "Invalid key \"%s\". Looking for values " \ "for type \"%s\", got \"%s\"", \ (_key), \ _bson_json_type_name (bson->bson_type), \ _bson_json_type_name (_type)); \ return; \ } \ bson->bson_type = (_type); \ bson->bson_state = (_state); \ } 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; jsonsl_stop (reader->json); } static void _bson_json_read_corrupt (bson_json_reader_t *reader, const char *fmt, ...) BSON_GNUC_PRINTF (2, 3); static void _bson_json_read_corrupt (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_CORRUPT_JS; 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; jsonsl_stop (reader->json); } 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_buf_set (bson_json_buf_t *buf, const void *from, size_t len) { _bson_json_buf_ensure (buf, len + 1); memcpy (buf->buf, from, len); buf->buf[len] = '\0'; buf->len = len; } static void _bson_json_buf_append (bson_json_buf_t *buf, const void *from, size_t len) { size_t len_with_null = len + 1; if (buf->len == 0) { _bson_json_buf_ensure (buf, len_with_null); } else if (buf->n_bytes < buf->len + len_with_null) { buf->n_bytes = bson_next_power_of_two (buf->len + len_with_null); buf->buf = bson_realloc (buf->buf, buf->n_bytes); } memcpy (buf->buf + buf->len, from, len); buf->len += len; buf->buf[buf->len] = '\0'; } static const char * _bson_json_type_name (bson_type_t type) { switch (type) { case BSON_TYPE_EOD: return "end of document"; case BSON_TYPE_DOUBLE: return "double"; case BSON_TYPE_UTF8: return "utf-8"; case BSON_TYPE_DOCUMENT: return "document"; case BSON_TYPE_ARRAY: return "array"; case BSON_TYPE_BINARY: return "binary"; case BSON_TYPE_UNDEFINED: return "undefined"; case BSON_TYPE_OID: return "objectid"; case BSON_TYPE_BOOL: return "bool"; case BSON_TYPE_DATE_TIME: return "datetime"; case BSON_TYPE_NULL: return "null"; case BSON_TYPE_REGEX: return "regex"; case BSON_TYPE_DBPOINTER: return "dbpointer"; case BSON_TYPE_CODE: return "code"; case BSON_TYPE_SYMBOL: return "symbol"; case BSON_TYPE_CODEWSCOPE: return "code with scope"; case BSON_TYPE_INT32: return "int32"; case BSON_TYPE_TIMESTAMP: return "timestamp"; case BSON_TYPE_INT64: return "int64"; case BSON_TYPE_DECIMAL128: return "decimal128"; case BSON_TYPE_MAXKEY: return "maxkey"; case BSON_TYPE_MINKEY: return "minkey"; default: return ""; } } static void _bson_json_read_fixup_key (bson_json_reader_bson_t *bson) /* IN */ { bson_json_read_state_t rs = bson->read_state; if (bson->n >= 0 && STACK_IS_ARRAY && rs == BSON_JSON_REGULAR) { _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_read_null (bson_json_reader_t *reader) { BASIC_CB_PREAMBLE; BASIC_CB_BAIL_IF_NOT_NORMAL ("null"); bson_append_null (STACK_BSON_CHILD, key, (int) len); } static void _bson_json_read_boolean (bson_json_reader_t *reader, /* IN */ int val) /* IN */ { BASIC_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; } BASIC_CB_BAIL_IF_NOT_NORMAL ("boolean"); bson_append_bool (STACK_BSON_CHILD, key, (int) len, val); } /* sign is -1 or 1 */ static void _bson_json_read_integer (bson_json_reader_t *reader, uint64_t val, int64_t sign) { bson_json_read_state_t rs; bson_json_read_bson_state_t bs; BASIC_CB_PREAMBLE; if (sign == 1 && val > INT64_MAX) { _bson_json_read_set_error ( reader, "Number \"%" PRIu64 "\" is out of range", val); return; } else if (sign == -1 && val > ((uint64_t) INT64_MAX + 1)) { _bson_json_read_set_error ( reader, "Number \"-%" PRIu64 "\" is out of range", val); return; } rs = bson->read_state; bs = bson->bson_state; if (rs == BSON_JSON_REGULAR) { BASIC_CB_BAIL_IF_NOT_NORMAL ("integer"); if (val <= INT32_MAX || (sign == -1 && val <= (uint64_t) INT32_MAX + 1)) { bson_append_int32 ( STACK_BSON_CHILD, key, (int) len, (int) (val * sign)); } else if (sign == -1) { bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) -val); } else { bson_append_int64 (STACK_BSON_CHILD, key, (int) len, (int64_t) 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 = sign * val; break; case BSON_JSON_LF_TIMESTAMP_T: if (sign == -1) { _bson_json_read_set_error ( reader, "Invalid timestamp value: \"-%" PRIu64 "\"", val); return; } bson->bson_type_data.timestamp.has_t = true; bson->bson_type_data.timestamp.t = (uint32_t) val; break; case BSON_JSON_LF_TIMESTAMP_I: if (sign == -1) { _bson_json_read_set_error ( reader, "Invalid timestamp value: \"-%" PRIu64 "\"", val); return; } bson->bson_type_data.timestamp.has_i = true; bson->bson_type_data.timestamp.i = (uint32_t) val; break; case BSON_JSON_LF_MINKEY: if (sign == -1) { _bson_json_read_set_error ( reader, "Invalid MinKey value: \"-%" PRIu64 "\"", val); return; } else if (val != 1) { _bson_json_read_set_error ( reader, "Invalid MinKey value: \"%" PRIu64 "\"", val); } bson->bson_type_data.minkey.has_minkey = true; break; case BSON_JSON_LF_MAXKEY: if (sign == -1) { _bson_json_read_set_error ( reader, "Invalid MinKey value: \"-%" PRIu64 "\"", val); return; } else if (val != 1) { _bson_json_read_set_error ( reader, "Invalid MinKey value: \"%" PRIu64 "\"", val); } bson->bson_type_data.maxkey.has_maxkey = true; break; case BSON_JSON_LF_INT32: case BSON_JSON_LF_INT64: _bson_json_read_set_error ( reader, "Invalid state for integer read: %s, " "expected number as quoted string like \"123\"", bson_state_names[bs]); break; case BSON_JSON_LF_REGEX: case BSON_JSON_LF_OPTIONS: case BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN: case BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS: case BSON_JSON_LF_CODE: case BSON_JSON_LF_SCOPE: case BSON_JSON_LF_OID: case BSON_JSON_LF_BINARY: case BSON_JSON_LF_TYPE: case BSON_JSON_LF_UNDEFINED: case BSON_JSON_LF_DOUBLE: case BSON_JSON_LF_DECIMAL128: case BSON_JSON_LF_DBPOINTER: case BSON_JSON_LF_SYMBOL: case BSON_JSON_LF_DBREF: default: _bson_json_read_set_error (reader, "Unexpected integer %s%" PRIu64 " in type \"%s\"", sign == -1 ? "-" : "", val, _bson_json_type_name (bson->bson_type)); } } else { _bson_json_read_set_error (reader, "Unexpected integer %s%" PRIu64 " in state \"%s\"", sign == -1 ? "-" : "", val, read_state_names[rs]); } } static bool _bson_json_parse_double (bson_json_reader_t *reader, const char *val, size_t vlen, double *d) { errno = 0; *d = strtod (val, NULL); #ifdef _MSC_VER /* Microsoft's strtod parses "NaN", "Infinity", "-Infinity" as 0 */ if (*d == 0.0) { if (!_strnicmp (val, "nan", vlen)) { #ifdef NAN *d = NAN; #else /* Visual Studio 2010 doesn't define NAN or INFINITY * https://msdn.microsoft.com/en-us/library/w22adx1s(v=vs.100).aspx */ unsigned long nan[2] = {0xffffffff, 0x7fffffff}; *d = *(double *) nan; #endif return true; } else if (!_strnicmp (val, "infinity", vlen)) { #ifdef INFINITY *d = INFINITY; #else unsigned long inf[2] = {0x00000000, 0x7ff00000}; *d = *(double *) inf; #endif return true; } else if (!_strnicmp (val, "-infinity", vlen)) { #ifdef INFINITY *d = -INFINITY; #else unsigned long inf[2] = {0x00000000, 0xfff00000}; *d = *(double *) inf; #endif return true; } } if ((*d == HUGE_VAL || *d == -HUGE_VAL) && errno == ERANGE) { _bson_json_read_set_error ( reader, "Number \"%.*s\" is out of range", (int) vlen, val); return false; } #else /* not MSVC - set err on overflow, but avoid err for infinity */ if ((*d == HUGE_VAL || *d == -HUGE_VAL) && errno == ERANGE && strncasecmp (val, "infinity", vlen) && strncasecmp (val, "-infinity", vlen)) { _bson_json_read_set_error ( reader, "Number \"%.*s\" is out of range", (int) vlen, val); return false; } #endif /* _MSC_VER */ return true; } static void _bson_json_read_double (bson_json_reader_t *reader, /* IN */ double val) /* IN */ { BASIC_CB_PREAMBLE; BASIC_CB_BAIL_IF_NOT_NORMAL ("double"); bson_append_double (STACK_BSON_CHILD, key, (int) len, val); } static bool _bson_json_read_int64_or_set_error (bson_json_reader_t *reader, /* IN */ const unsigned char *val, /* IN */ size_t vlen, /* IN */ int64_t *v64) /* OUT */ { bson_json_reader_bson_t *bson = &reader->bson; char *endptr = NULL; _bson_json_read_fixup_key (bson); errno = 0; *v64 = bson_ascii_strtoll ((const char *) val, &endptr, 10); if (((*v64 == INT64_MIN) || (*v64 == INT64_MAX)) && (errno == ERANGE)) { _bson_json_read_set_error (reader, "Number \"%s\" is out of range", val); return false; } if (endptr != ((const char *) val + vlen)) { _bson_json_read_set_error (reader, "Number \"%s\" is invalid", val); return false; } return true; } /* parse a value for "base64", "subType" or legacy "$binary" or "$type" */ static void _bson_json_parse_binary_elem (bson_json_reader_t *reader, const char *val_w_null, size_t vlen) { bson_json_read_bson_state_t bs; bson_json_bson_data_t *data; int binary_len; BASIC_CB_PREAMBLE; bs = bson->bson_state; data = &bson->bson_type_data; if (bs == BSON_JSON_LF_BINARY) { data->binary.has_binary = true; binary_len = b64_pton (val_w_null, NULL, 0); if (binary_len < 0) { _bson_json_read_set_error ( reader, "Invalid input string \"%s\", looking for base64-encoded binary", val_w_null); } _bson_json_buf_ensure (&bson->bson_type_buf[0], (size_t) binary_len + 1); b64_pton ( val_w_null, bson->bson_type_buf[0].buf, (size_t) binary_len + 1); bson->bson_type_buf[0].len = (size_t) binary_len; } else if (bs == BSON_JSON_LF_TYPE) { data->binary.has_subtype = true; if (SSCANF (val_w_null, "%02x", &data->binary.type) != 1) { if (!data->binary.is_legacy || data->binary.has_binary) { /* misformatted subtype, like {$binary: {base64: "", subType: "x"}}, * or legacy {$binary: "", $type: "x"} */ _bson_json_read_set_error ( reader, "Invalid input string \"%s\", looking for binary subtype", val_w_null); } else { /* actually a query operator: {x: {$type: "array"}}*/ bson->read_state = BSON_JSON_REGULAR; STACK_PUSH_DOC (bson_append_document_begin ( STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD)); bson_append_utf8 (STACK_BSON_CHILD, "$type", 5, (const char *) val_w_null, (int) vlen); } } } } static void _bson_json_read_string (bson_json_reader_t *reader, /* IN */ const unsigned char *val, /* IN */ size_t vlen) /* IN */ { bson_json_read_state_t rs; bson_json_read_bson_state_t bs; BASIC_CB_PREAMBLE; rs = bson->read_state; bs = bson->bson_state; if (!bson_utf8_validate ((const char *) val, vlen, true /*allow null*/)) { _bson_json_read_corrupt (reader, "invalid bytes in UTF8 string"); return; } if (rs == BSON_JSON_REGULAR) { BASIC_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_SCOPE_STARTMAP || rs == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) { _bson_json_read_set_error (reader, "Invalid read of \"%s\" in state \"%s\"", val, read_state_names[rs]); } else if (rs == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) { const char *val_w_null; _bson_json_buf_set (&bson->bson_type_buf[2], val, vlen); val_w_null = (const char *) bson->bson_type_buf[2].buf; _bson_json_parse_binary_elem (reader, val_w_null, vlen); } else if (rs == BSON_JSON_IN_BSON_TYPE || rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES || rs == BSON_JSON_IN_BSON_TYPE_REGEX_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); val_w_null = (const char *) bson->bson_type_buf[2].buf; switch (bs) { case BSON_JSON_LF_REGEX: bson->bson_type_data.regex.is_legacy = true; /* FALL THROUGH */ case BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN: bson->bson_type_data.regex.has_pattern = true; _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen); break; case BSON_JSON_LF_OPTIONS: bson->bson_type_data.regex.is_legacy = true; /* FALL THROUGH */ case BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS: bson->bson_type_data.regex.has_options = true; _bson_json_buf_set (&bson->bson_type_buf[1], val, vlen); 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_BINARY: case BSON_JSON_LF_TYPE: bson->bson_type_data.binary.is_legacy = true; _bson_json_parse_binary_elem (reader, val_w_null, vlen); break; case BSON_JSON_LF_INT32: { int64_t v64; if (!_bson_json_read_int64_or_set_error (reader, val, vlen, &v64)) { /* the error is set, return and let the reader exit */ return; } if (v64 < INT32_MIN || v64 > INT32_MAX) { goto BAD_PARSE; } if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { bson->bson_type_data.v_int32.value = (int32_t) v64; } else { goto BAD_PARSE; } } break; case BSON_JSON_LF_INT64: { int64_t v64; if (!_bson_json_read_int64_or_set_error (reader, val, vlen, &v64)) { /* the error is set, return and let the reader exit */ return; } 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_DOUBLE: { _bson_json_parse_double (reader, (const char *) val, vlen, &bson->bson_type_data.v_double.value); } break; case BSON_JSON_LF_DATE: { int64_t v64; if (!_bson_iso8601_date_parse ( (char *) val, (int) vlen, &v64, reader->error)) { jsonsl_stop (reader->json); } else { bson->bson_type_data.date.has_date = true; bson->bson_type_data.date.date = v64; } } break; case BSON_JSON_LF_DECIMAL128: { bson_decimal128_t decimal128; bson_decimal128_from_string (val_w_null, &decimal128); if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { bson->bson_type_data.v_decimal128.value = decimal128; } else { goto BAD_PARSE; } } break; case BSON_JSON_LF_CODE: _bson_json_buf_set (&bson->code_data.code_buf, val, vlen); break; case BSON_JSON_LF_SYMBOL: bson_append_symbol ( STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen); break; case BSON_JSON_LF_DBREF: /* the "$ref" of a {$ref: "...", $id: ... }, append normally */ bson_append_utf8 ( STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen); bson->read_state = BSON_JSON_REGULAR; break; case BSON_JSON_LF_SCOPE: 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: case BSON_JSON_LF_DBPOINTER: default: goto BAD_PARSE; } return; BAD_PARSE: _bson_json_read_set_error (reader, "Invalid input string \"%s\", looking for %s", val_w_null, bson_state_names[bs]); } else { _bson_json_read_set_error ( reader, "Invalid state to look for string: %s", read_state_names[rs]); } } static void _bson_json_read_start_map (bson_json_reader_t *reader) /* IN */ { BASIC_CB_PREAMBLE; if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { if (bson->bson_state == BSON_JSON_LF_DATE) { bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG; } else if (bson->bson_state == BSON_JSON_LF_BINARY) { bson->read_state = BSON_JSON_IN_BSON_TYPE_BINARY_VALUES; } else if (bson->bson_state == BSON_JSON_LF_TYPE) { /* special case, we started parsing {$type: {$numberInt: "2"}} and we * expected a legacy Binary format. now we see the second "{", so * backtrack and parse $type query operator. */ bson->read_state = BSON_JSON_IN_START_MAP; STACK_PUSH_DOC (bson_append_document_begin ( STACK_BSON_PARENT, key, len, STACK_BSON_CHILD)); _bson_json_save_map_key (bson, (const uint8_t *) "$type", 5); } } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP) { bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) { bson->read_state = BSON_JSON_IN_SCOPE; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) { bson->read_state = BSON_JSON_IN_DBPOINTER; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_STARTMAP) { bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_VALUES; } else { bson->read_state = BSON_JSON_IN_START_MAP; } /* silence some warnings */ (void) len; (void) key; } 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 ("$regularExpression") || IS_KEY ("$regex") || IS_KEY ("$options") || IS_KEY ("$code") || IS_KEY ("$scope") || 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 ("$numberInt") || IS_KEY ("$numberLong") || IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") || IS_KEY ("$numberInt") || IS_KEY ("$numberLong") || IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") || IS_KEY ("$dbPointer") || IS_KEY ("$symbol")); #undef IS_KEY return ret; } static void _bson_json_save_map_key (bson_json_reader_bson_t *bson, const uint8_t *val, size_t len) { _bson_json_buf_set (&bson->key_buf, val, len); bson->key = (const char *) bson->key_buf.buf; } static void _bson_json_read_code_or_scope_key (bson_json_reader_bson_t *bson, bool is_scope, const uint8_t *val, size_t len) { bson_json_code_t *code = &bson->code_data; if (code->in_scope) { /* we're reading something weirdly nested, e.g. we just read "$code" in * "$scope: {x: {$code: {}}}". just create the subdoc within the scope. */ 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)); _bson_json_save_map_key (bson, val, len); } else { if (!bson->code_data.key_buf.len) { /* save the key, e.g. {"key": {"$code": "return x", "$scope":{"x":1}}}, * in case it is overwritten while parsing scope sub-object */ _bson_json_buf_set ( &bson->code_data.key_buf, bson->key_buf.buf, bson->key_buf.len); } if (is_scope) { bson->bson_type = BSON_TYPE_CODEWSCOPE; bson->read_state = BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP; bson->bson_state = BSON_JSON_LF_SCOPE; bson->code_data.has_scope = true; } else { bson->bson_type = BSON_TYPE_CODE; bson->bson_state = BSON_JSON_LF_CODE; bson->code_data.has_code = true; } } } static void _bson_json_bad_key_in_type (bson_json_reader_t *reader, /* IN */ const uint8_t *val) /* IN */ { bson_json_reader_bson_t *bson = &reader->bson; _bson_json_read_set_error ( reader, "Invalid key \"%s\". Looking for values for type \"%s\"", val, _bson_json_type_name (bson->bson_type)); } static void _bson_json_read_map_key (bson_json_reader_t *reader, /* IN */ const uint8_t *val, /* IN */ size_t len) /* IN */ { bson_json_reader_bson_t *bson = &reader->bson; if (!bson_utf8_validate ((const char *) val, len, true /* allow null */)) { _bson_json_read_corrupt (reader, "invalid bytes in UTF8 string"); return; } if (bson->read_state == BSON_JSON_IN_START_MAP) { if (len > 0 && val[0] == '$' && _is_known_key ((const char *) val, len) && bson->n >= 0 /* key is in subdocument */) { 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)); } } else if (bson->read_state == BSON_JSON_IN_SCOPE) { /* we've read "key" in {$code: "", $scope: {key: ""}}*/ bson->read_state = BSON_JSON_REGULAR; STACK_PUSH_SCOPE (bson_init (STACK_BSON_CHILD)); _bson_json_save_map_key (bson, val, len); } else if (bson->read_state == BSON_JSON_IN_DBPOINTER) { /* we've read "$ref" or "$id" in {$dbPointer: {$ref: ..., $id: ...}} */ bson->read_state = BSON_JSON_REGULAR; STACK_PUSH_DBPOINTER (bson_init (STACK_BSON_CHILD)); _bson_json_save_map_key (bson, val, len); } 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 ("$numberInt", BSON_TYPE_INT32, BSON_JSON_LF_INT32) else if HANDLE_OPTION ("$numberLong", BSON_TYPE_INT64, BSON_JSON_LF_INT64) else if HANDLE_OPTION ("$numberDouble", BSON_TYPE_DOUBLE, BSON_JSON_LF_DOUBLE) else if HANDLE_OPTION ("$symbol", BSON_TYPE_SYMBOL, BSON_JSON_LF_SYMBOL) else if HANDLE_OPTION ( "$numberDecimal", BSON_TYPE_DECIMAL128, BSON_JSON_LF_DECIMAL128) else if (!strcmp ("$timestamp", (const char *) val)) { bson->bson_type = BSON_TYPE_TIMESTAMP; bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP; } else if (!strcmp ("$regularExpression", (const char *) val)) { bson->bson_type = BSON_TYPE_REGEX; bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_STARTMAP; } else if (!strcmp ("$dbPointer", (const char *) val)) { /* start parsing "key": {"$dbPointer": {...}}, save "key" for later */ _bson_json_buf_set ( &bson->dbpointer_key, bson->key_buf.buf, bson->key_buf.len); bson->bson_type = BSON_TYPE_DBPOINTER; bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP; } else if (!strcmp ("$code", (const char *) val)) { _bson_json_read_code_or_scope_key ( bson, false /* is_scope */, val, len); } else if (!strcmp ("$scope", (const char *) val)) { _bson_json_read_code_or_scope_key ( bson, true /* is_scope */, val, len); } else { _bson_json_bad_key_in_type (reader, val); } } 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_bad_key_in_type (reader, val); } } 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_bad_key_in_type (reader, val); } } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES) { if HANDLE_OPTION ( "pattern", BSON_TYPE_REGEX, BSON_JSON_LF_REGULAR_EXPRESSION_PATTERN) else if HANDLE_OPTION ( "options", BSON_TYPE_REGEX, BSON_JSON_LF_REGULAR_EXPRESSION_OPTIONS) else { _bson_json_bad_key_in_type (reader, val); } } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) { if HANDLE_OPTION ("base64", BSON_TYPE_BINARY, BSON_JSON_LF_BINARY) else if HANDLE_OPTION ("subType", BSON_TYPE_BINARY, BSON_JSON_LF_TYPE) else { _bson_json_bad_key_in_type (reader, val); } } else { _bson_json_save_map_key (bson, val, len); /* in x: {$ref: "collection", $id: {$oid: "..."}, $db: "..." } */ if (bson->n > 0) { if (!strcmp ("$ref", (const char *) val)) { STACK_HAS_REF = true; bson->read_state = BSON_JSON_IN_BSON_TYPE; bson->bson_state = BSON_JSON_LF_DBREF; } else if (!strcmp ("$id", (const char *) val)) { STACK_HAS_ID = true; } else if (!strcmp ("$db", (const char *) val)) { bson->read_state = BSON_JSON_IN_BSON_TYPE; bson->bson_state = BSON_JSON_LF_DBREF; } } } } static void _bson_json_read_append_binary (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { bson_json_bson_data_t *data = &bson->bson_type_data; if (data->binary.is_legacy) { if (!data->binary.has_binary) { _bson_json_read_set_error ( reader, "Missing \"$binary\" after \"$type\" reading type \"binary\""); return; } else if (!data->binary.has_subtype) { _bson_json_read_set_error ( reader, "Missing \"$type\" after \"$binary\" reading type \"binary\""); return; } } else { if (!data->binary.has_binary) { _bson_json_read_set_error ( reader, "Missing \"base64\" after \"subType\" reading type \"binary\""); return; } else if (!data->binary.has_subtype) { _bson_json_read_set_error ( reader, "Missing \"subType\" after \"base64\" reading type \"binary\""); return; } } if (!bson_append_binary (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, data->binary.type, bson->bson_type_buf[0].buf, (uint32_t) bson->bson_type_buf[0].len)) { _bson_json_read_set_error (reader, "Error storing binary data"); } } static void _bson_json_read_append_regex (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { bson_json_bson_data_t *data = &bson->bson_type_data; if (data->regex.is_legacy) { if (!data->regex.has_pattern) { _bson_json_read_set_error (reader, "Missing \"$regex\" after \"$options\""); return; } if (!data->regex.has_options) { _bson_json_read_set_error (reader, "Missing \"$options\" after \"$regex\""); return; } } else if (!data->regex.has_pattern) { _bson_json_read_set_error ( reader, "Missing \"pattern\" after \"options\" in regular expression"); return; } else if (!data->regex.has_options) { _bson_json_read_set_error ( reader, "Missing \"options\" after \"pattern\" in regular expression"); return; } if (!bson_append_regex (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, (char *) bson->bson_type_buf[0].buf, (char *) bson->bson_type_buf[1].buf)) { _bson_json_read_set_error (reader, "Error storing regex"); } } static void _bson_json_read_append_code (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { bson_json_code_t *code_data; char *code = NULL; bson_t *scope = NULL; bool r; code_data = &bson->code_data; BSON_ASSERT (!code_data->in_scope); if (!code_data->has_code) { _bson_json_read_set_error (reader, "Missing $code after $scope"); return; } code = (char *) code_data->code_buf.buf; if (code_data->has_scope) { scope = STACK_BSON (1); } /* creates BSON "code" elem, or "code with scope" if scope is not NULL */ r = bson_append_code_with_scope (STACK_BSON_CHILD, (const char *) code_data->key_buf.buf, (int) code_data->key_buf.len, code, scope); if (!r) { _bson_json_read_set_error (reader, "Error storing Javascript code"); } if (scope) { bson_destroy (scope); } /* keep the buffer but truncate it */ code_data->key_buf.len = 0; code_data->has_code = code_data->has_scope = false; } static void _bson_json_read_append_dbpointer (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { bson_t *db_pointer; bson_iter_t iter; const char *ns = NULL; const bson_oid_t *oid = NULL; bool r; BSON_ASSERT (reader->bson.dbpointer_key.buf); db_pointer = STACK_BSON (1); if (!bson_iter_init (&iter, db_pointer)) { _bson_json_read_set_error (reader, "Error storing DBPointer"); return; } while (bson_iter_next (&iter)) { if (!strcmp (bson_iter_key (&iter), "$id")) { if (!BSON_ITER_HOLDS_OID (&iter)) { _bson_json_read_set_error ( reader, "$dbPointer.$id must be like {\"$oid\": ...\"}"); return; } oid = bson_iter_oid (&iter); } else if (!strcmp (bson_iter_key (&iter), "$ref")) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) { _bson_json_read_set_error ( reader, "$dbPointer.$ref must be a string like \"db.collection\""); return; } ns = bson_iter_utf8 (&iter, NULL); } else { _bson_json_read_set_error (reader, "$dbPointer contains invalid key: \"%s\"", bson_iter_key (&iter)); return; } } if (!oid || !ns) { _bson_json_read_set_error (reader, "$dbPointer requires both $id and $ref"); return; } r = bson_append_dbpointer (STACK_BSON_CHILD, (char *) reader->bson.dbpointer_key.buf, (int) reader->bson.dbpointer_key.len, ns, oid); if (!r) { _bson_json_read_set_error (reader, "Error storing DBPointer"); } } static void _bson_json_read_append_oid (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { if (!bson_append_oid (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, &bson->bson_type_data.oid.oid)) { _bson_json_read_set_error (reader, "Error storing ObjectId"); } } static void _bson_json_read_append_date_time (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { if (!bson_append_date_time (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, bson->bson_type_data.date.date)) { _bson_json_read_set_error (reader, "Error storing datetime"); } } static void _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; } else if (!bson->bson_type_data.timestamp.has_i) { _bson_json_read_set_error ( reader, "Missing i after $timestamp in BSON_TYPE_TIMESTAMP"); 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 void _bad_extended_json (bson_json_reader_t *reader) { _bson_json_read_corrupt (reader, "Invalid MongoDB extended JSON"); } static void _bson_json_read_end_map (bson_json_reader_t *reader) /* IN */ { 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)); } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) { bson->read_state = BSON_JSON_REGULAR; STACK_PUSH_SCOPE (bson_init (STACK_BSON_CHILD)); } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) { /* we've read last "}" in "{$dbPointer: {$id: ..., $ref: ...}}" */ _bson_json_read_append_dbpointer (reader, bson); bson->read_state = BSON_JSON_REGULAR; return; } if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { if (!bson->key) { /* invalid, like {$numberLong: "1"} at the document top level */ _bad_extended_json (reader); return; } bson->read_state = BSON_JSON_REGULAR; switch (bson->bson_type) { case BSON_TYPE_REGEX: _bson_json_read_append_regex (reader, bson); break; case BSON_TYPE_CODE: case BSON_TYPE_CODEWSCOPE: /* we've read the closing "}" in "{$code: ..., $scope: ...}" */ _bson_json_read_append_code (reader, bson); break; case BSON_TYPE_OID: _bson_json_read_append_oid (reader, bson); break; case BSON_TYPE_BINARY: _bson_json_read_append_binary (reader, bson); break; case BSON_TYPE_DATE_TIME: _bson_json_read_append_date_time (reader, bson); break; case BSON_TYPE_UNDEFINED: bson_append_undefined ( STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len); break; case BSON_TYPE_MINKEY: bson_append_minkey ( STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len); break; case BSON_TYPE_MAXKEY: bson_append_maxkey ( STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len); break; case BSON_TYPE_INT32: bson_append_int32 (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, bson->bson_type_data.v_int32.value); break; case BSON_TYPE_INT64: bson_append_int64 (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, bson->bson_type_data.v_int64.value); break; case BSON_TYPE_DOUBLE: bson_append_double (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, bson->bson_type_data.v_double.value); break; case BSON_TYPE_DECIMAL128: bson_append_decimal128 (STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len, &bson->bson_type_data.v_decimal128.value); break; case BSON_TYPE_DBPOINTER: /* shouldn't set type to DBPointer unless inside $dbPointer: {...} */ _bson_json_read_set_error ( reader, "Internal error: shouldn't be in state BSON_TYPE_DBPOINTER"); break; case BSON_TYPE_SYMBOL: break; case BSON_TYPE_EOD: case BSON_TYPE_UTF8: case BSON_TYPE_DOCUMENT: case BSON_TYPE_ARRAY: case BSON_TYPE_BOOL: case BSON_TYPE_NULL: case BSON_TYPE_TIMESTAMP: default: _bson_json_read_set_error ( reader, "Internal error: can't parse JSON wrapper for type \"%s\"", _bson_json_type_name (bson->bson_type)); break; } } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) { if (!bson->key) { _bad_extended_json (reader); return; } bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP; _bson_json_read_append_timestamp (reader, bson); return; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_REGEX_VALUES) { if (!bson->key) { _bad_extended_json (reader); return; } bson->read_state = BSON_JSON_IN_BSON_TYPE_REGEX_ENDMAP; _bson_json_read_append_regex (reader, bson); return; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_VALUES) { if (!bson->key) { _bad_extended_json (reader); return; } bson->read_state = BSON_JSON_IN_BSON_TYPE_BINARY_ENDMAP; _bson_json_read_append_binary (reader, bson); return; } 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_REGEX_ENDMAP) { bson->read_state = BSON_JSON_REGULAR; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_BINARY_ENDMAP) { bson->read_state = BSON_JSON_REGULAR; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) { if (!bson->key) { _bad_extended_json (reader); return; } bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP; _bson_json_read_append_date_time (reader, bson); return; } 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) { if (STACK_IS_SCOPE) { bson->read_state = BSON_JSON_IN_BSON_TYPE; bson->bson_type = BSON_TYPE_CODE; STACK_POP_SCOPE; } else if (STACK_IS_DBPOINTER) { bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP; STACK_POP_DBPOINTER; } else { if (STACK_HAS_ID != STACK_HAS_REF) { _bson_json_read_set_error ( reader, "%s", "DBRef object must have both $ref and $id keys"); } STACK_POP_DOC ( bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD)); } if (bson->n == -1) { bson->read_state = BSON_JSON_DONE; } } else if (bson->read_state == BSON_JSON_IN_SCOPE) { /* empty $scope */ BSON_ASSERT (bson->code_data.has_scope); STACK_PUSH_SCOPE (bson_init (STACK_BSON_CHILD)); STACK_POP_SCOPE; bson->read_state = BSON_JSON_IN_BSON_TYPE; bson->bson_type = BSON_TYPE_CODE; } else if (bson->read_state == BSON_JSON_IN_DBPOINTER) { /* empty $dbPointer??? */ _bson_json_read_set_error (reader, "Empty $dbPointer"); } else { _bson_json_read_set_error ( reader, "Invalid state \"%s\"", read_state_names[bson->read_state]); } } static void _bson_json_read_start_array (bson_json_reader_t *reader) /* IN */ { const char *key; size_t len; 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; if (bson->read_state != BSON_JSON_REGULAR) { _bson_json_read_set_error (reader, "Invalid read of \"[\" in state \"%s\"", read_state_names[bson->read_state]); return; } STACK_PUSH_ARRAY (bson_append_array_begin ( STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD)); } } static void _bson_json_read_end_array (bson_json_reader_t *reader) /* IN */ { bson_json_reader_bson_t *bson = &reader->bson; if (bson->read_state != BSON_JSON_REGULAR) { _bson_json_read_set_error (reader, "Invalid read of \"]\" in state \"%s\"", read_state_names[bson->read_state]); return; } STACK_POP_ARRAY ( bson_append_array_end (STACK_BSON_PARENT, STACK_BSON_CHILD)); if (bson->n == -1) { bson->read_state = BSON_JSON_DONE; } } /* put unescaped text in reader->bson.unescaped, or set reader->error. * json_text has length len and it is not null-terminated. */ static bool _bson_json_unescape (bson_json_reader_t *reader, struct jsonsl_state_st *state, const char *json_text, ssize_t len) { bson_json_reader_bson_t *reader_bson; jsonsl_error_t err; reader_bson = &reader->bson; /* add 1 for NULL */ _bson_json_buf_ensure (&reader_bson->unescaped, (size_t) len + 1); /* length of unescaped str is always <= len */ reader_bson->unescaped.len = jsonsl_util_unescape ( json_text, (char *) reader_bson->unescaped.buf, (size_t) len, NULL, &err); if (err != JSONSL_ERROR_SUCCESS) { bson_set_error (reader->error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_CORRUPT_JS, "error near position %d: \"%s\"", (int) state->pos_begin, jsonsl_strerror (err)); return false; } reader_bson->unescaped.buf[reader_bson->unescaped.len] = '\0'; return true; } /* read the buffered JSON plus new data, and fill out @len with its length */ static const char * _get_json_text (jsonsl_t json, /* IN */ struct jsonsl_state_st *state, /* IN */ const char *buf /* IN */, ssize_t *len /* OUT */) { bson_json_reader_t *reader; ssize_t bytes_available; reader = (bson_json_reader_t *) json->data; BSON_ASSERT (state->pos_cur > state->pos_begin); *len = (ssize_t) (state->pos_cur - state->pos_begin); bytes_available = buf - json->base; if (*len <= bytes_available) { /* read directly from stream, not from saved JSON */ return buf - (size_t) *len; } else { /* combine saved text with new data from the jsonsl_t */ ssize_t append = buf - json->base; if (append > 0) { _bson_json_buf_append ( &reader->tok_accumulator, buf - append, (size_t) append); } return (const char *) reader->tok_accumulator.buf; } } static void _push_callback (jsonsl_t json, jsonsl_action_t action, struct jsonsl_state_st *state, const char *buf) { bson_json_reader_t *reader = (bson_json_reader_t *) json->data; switch (state->type) { case JSONSL_T_STRING: case JSONSL_T_HKEY: case JSONSL_T_SPECIAL: case JSONSL_T_UESCAPE: reader->json_text_pos = state->pos_begin; break; case JSONSL_T_OBJECT: _bson_json_read_start_map (reader); break; case JSONSL_T_LIST: _bson_json_read_start_array (reader); break; default: break; } } static void _pop_callback (jsonsl_t json, jsonsl_action_t action, struct jsonsl_state_st *state, const char *buf) { bson_json_reader_t *reader; bson_json_reader_bson_t *reader_bson; ssize_t len; double d; const char *obj_text; reader = (bson_json_reader_t *) json->data; reader_bson = &reader->bson; switch (state->type) { case JSONSL_T_HKEY: case JSONSL_T_STRING: obj_text = _get_json_text (json, state, buf, &len); BSON_ASSERT (obj_text[0] == '"'); /* remove start/end quotes, replace backslash-escapes, null-terminate */ /* you'd think it would be faster to check if state->nescapes > 0 first, * but tests show no improvement */ if (!_bson_json_unescape (reader, state, obj_text + 1, len - 1)) { /* reader->error is set */ jsonsl_stop (json); break; } if (state->type == JSONSL_T_HKEY) { _bson_json_read_map_key ( reader, reader_bson->unescaped.buf, reader_bson->unescaped.len); } else { _bson_json_read_string ( reader, reader_bson->unescaped.buf, reader_bson->unescaped.len); } break; case JSONSL_T_OBJECT: _bson_json_read_end_map (reader); break; case JSONSL_T_LIST: _bson_json_read_end_array (reader); break; case JSONSL_T_SPECIAL: obj_text = _get_json_text (json, state, buf, &len); if (state->special_flags & JSONSL_SPECIALf_NUMNOINT) { if (_bson_json_parse_double (reader, obj_text, (size_t) len, &d)) { _bson_json_read_double (reader, d); } } else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) { /* jsonsl puts the unsigned value in state->nelem */ _bson_json_read_integer ( reader, state->nelem, state->special_flags & JSONSL_SPECIALf_SIGNED ? -1 : 1); } else if (state->special_flags & JSONSL_SPECIALf_BOOLEAN) { _bson_json_read_boolean (reader, obj_text[0] == 't' ? 1 : 0); } else if (state->special_flags & JSONSL_SPECIALf_NULL) { _bson_json_read_null (reader); } break; default: break; } reader->json_text_pos = -1; reader->tok_accumulator.len = 0; } static int _error_callback (jsonsl_t json, jsonsl_error_t err, struct jsonsl_state_st *state, char *errat) { bson_json_reader_t *reader = (bson_json_reader_t *) json->data; if (err == JSONSL_ERROR_CANT_INSERT && *errat == '{') { /* start the next document */ reader->should_reset = true; reader->advance = errat - json->base; return 0; } else if (err == JSONSL_ERROR_WEIRD_WHITESPACE && *errat == '\0') { /* embedded NULL is ok */ json->pos++; return 1; } bson_set_error (reader->error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_CORRUPT_JS, "Got parse error at \"%c\", position %d: \"%s\"", *errat, (int) json->pos, jsonsl_strerror (err)); return 0; } /* *-------------------------------------------------------------------------- * * 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; ssize_t start_pos; ssize_t r; ssize_t buf_offset; ssize_t accum; bson_error_t error_tmp; int ret = 0; BSON_ASSERT (reader); BSON_ASSERT (bson); p = &reader->producer; reader->bson.bson = bson; reader->bson.n = -1; reader->bson.read_state = BSON_JSON_REGULAR; reader->error = error ? error : &error_tmp; memset (reader->error, 0, sizeof (bson_error_t)); for (;;) { start_pos = reader->json->pos; if (p->bytes_read > 0) { /* leftover data from previous JSON doc in the stream */ r = p->bytes_read; } else { /* read a chunk of bytes by executing the callback */ r = p->cb (p->data, p->buf, p->buf_size); } 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 { ret = 1; p->bytes_read = (size_t) r; jsonsl_feed (reader->json, (const jsonsl_char_t *) p->buf, (size_t) r); if (reader->should_reset) { /* end of a document */ jsonsl_reset (reader->json); reader->should_reset = false; /* advance past already-parsed data */ memmove (p->buf, p->buf + reader->advance, r - reader->advance); p->bytes_read -= reader->advance; ret = 1; goto cleanup; } if (reader->error->domain) { ret = -1; goto cleanup; } /* accumulate a key or string value */ if (reader->json_text_pos != -1) { if (reader->json_text_pos < reader->json->pos) { accum = BSON_MIN (reader->json->pos - reader->json_text_pos, r); /* if this chunk stopped mid-token, buf_offset is how far into * our current chunk the token begins. */ buf_offset = AT_LEAST_0 (reader->json_text_pos - start_pos); _bson_json_buf_append (&reader->tok_accumulator, p->buf + buf_offset, (size_t) accum); } } p->bytes_read = 0; } } cleanup: if (ret == 1 && reader->bson.read_state != BSON_JSON_DONE) { /* data ended in the middle */ _bson_json_read_corrupt (reader, "%s", "Incomplete JSON"); return -1; } 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, /* unused */ size_t buf_size) /* IN */ { bson_json_reader_t *r; bson_json_reader_producer_t *p; r = bson_malloc0 (sizeof *r); r->json = jsonsl_new (STACK_MAX); r->json->error_callback = _error_callback; r->json->action_callback_PUSH = _push_callback; r->json->action_callback_POP = _pop_callback; r->json->data = r; r->json_text_pos = -1; jsonsl_enable_all_callbacks (r->json); 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); 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); bson_free (b->unescaped.buf); bson_free (b->dbpointer_key.buf); for (i = 0; i < 3; i++) { bson_free (b->bson_type_buf[i].buf); } _bson_json_code_cleanup (&b->code_data); jsonsl_destroy (reader->json); bson_free (reader->tok_accumulator.buf); 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 == 0) { bson_set_error (error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_INVALID_PARAM, "Empty JSON string"); } 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 == 0) { bson_set_error (error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_INVALID_PARAM, "Empty JSON string"); } 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.3.4/src/libbson/src/bson/bson-json.h0000664000175000017500000000425013210321137021026 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_EXPORT (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_EXPORT (bson_json_reader_t *) bson_json_reader_new_from_fd (int fd, bool close_on_destroy); BSON_EXPORT (bson_json_reader_t *) bson_json_reader_new_from_file (const char *filename, bson_error_t *error); BSON_EXPORT (void) bson_json_reader_destroy (bson_json_reader_t *reader); BSON_EXPORT (int) bson_json_reader_read (bson_json_reader_t *reader, bson_t *bson, bson_error_t *error); BSON_EXPORT (bson_json_reader_t *) bson_json_data_reader_new (bool allow_multiple, size_t size); BSON_EXPORT (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.3.4/src/libbson/src/bson/bson-keys.c0000664000175000017500000002234013210321137021023 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.3.4/src/libbson/src/bson/bson-keys.h0000664000175000017500000000164013210321137021030 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 BSON_EXPORT (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.3.4/src/libbson/src/bson/bson-macros.h0000664000175000017500000001532013210321137021341 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 #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 #if defined (__GNUC__) #define BSON_GNUC_CHECK_VERSION(major, minor) \ ((__GNUC__ > (major)) || \ ((__GNUC__ == (major)) && (__GNUC_MINOR__ >= (minor)))) #else #define BSON_GNUC_CHECK_VERSION(major, minor) 0 #endif #if defined (__GNUC__) #define BSON_GNUC_IS_VERSION(major, minor) \ ((__GNUC__ == (major)) && (__GNUC_MINOR__ == (minor))) #else #define BSON_GNUC_IS_VERSION(major, minor) 0 #endif /* Decorate public functions: * - if BSON_STATIC, we're compiling a program that uses libbson as a static * library, don't decorate functions * - else if BSON_COMPILATION, we're compiling a static or shared libbson, mark * public functions for export from the shared lib (which has no effect on * the static lib) * - else, we're compiling a program that uses libbson as a shared library, * mark public functions as DLL imports for Microsoft Visual C */ #ifdef _MSC_VER /* * Microsoft Visual C */ #ifdef BSON_STATIC #define BSON_API #elif defined(BSON_COMPILATION) #define BSON_API __declspec(dllexport) #else #define BSON_API __declspec(dllimport) #endif #define BSON_CALL __cdecl #elif defined(__GNUC__) /* * GCC */ #ifdef BSON_STATIC #define BSON_API #elif defined(BSON_COMPILATION) #define BSON_API __attribute__ ((visibility ("default"))) #else #define BSON_API #endif #define BSON_CALL #else /* * Other compilers */ #define BSON_API #define BSON_CALL #endif #define BSON_EXPORT(type) BSON_API type BSON_CALL #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 (BSON_ALIGN_OF_PTR)) #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.3.4/src/libbson/src/bson/bson-md5.c0000664000175000017500000003101213210321137020531 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.3.4/src/libbson/src/bson/bson-md5.h0000664000175000017500000000542513210321137020547 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; BSON_EXPORT (void) bson_md5_init (bson_md5_t *pms); BSON_EXPORT (void) bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes); BSON_EXPORT (void) bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]); BSON_END_DECLS #endif /* BSON_MD5_H */ mongodb-1.3.4/src/libbson/src/bson/bson-memory.c0000664000175000017500000001526013210321137021363 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 BSON_HAVE_REALLOCF 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 = NULL; if (BSON_LIKELY (num_bytes)) { if (BSON_UNLIKELY (!(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 BSON_HAVE_REALLOCF reallocf, #else realloc, #endif free, }; bson_mem_set_vtable (&vtable); } mongodb-1.3.4/src/libbson/src/bson/bson-memory.h0000664000175000017500000000322713210321137021370 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; BSON_EXPORT (void) bson_mem_set_vtable (const bson_mem_vtable_t *vtable); BSON_EXPORT (void) bson_mem_restore_vtable (void); BSON_EXPORT (void *) bson_malloc (size_t num_bytes); BSON_EXPORT (void *) bson_malloc0 (size_t num_bytes); BSON_EXPORT (void *) bson_realloc (void *mem, size_t num_bytes); BSON_EXPORT (void *) bson_realloc_ctx (void *mem, size_t num_bytes, void *ctx); BSON_EXPORT (void) bson_free (void *mem); BSON_EXPORT (void) bson_zero_free (void *mem, size_t size); BSON_END_DECLS #endif /* BSON_MEMORY_H */ mongodb-1.3.4/src/libbson/src/bson/bson-oid.c0000664000175000017500000003473113210321137020632 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__) && !defined(_M_IX86) && \ !defined(_M_X64) 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': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': break; default: return false; } } return true; } return false; } mongodb-1.3.4/src/libbson/src/bson/bson-oid.h0000664000175000017500000001373313210321137020636 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 BSON_EXPORT (int) bson_oid_compare (const bson_oid_t *oid1, const bson_oid_t *oid2); BSON_EXPORT (void) bson_oid_copy (const bson_oid_t *src, bson_oid_t *dst); BSON_EXPORT (bool) bson_oid_equal (const bson_oid_t *oid1, const bson_oid_t *oid2); BSON_EXPORT (bool) bson_oid_is_valid (const char *str, size_t length); BSON_EXPORT (time_t) bson_oid_get_time_t (const bson_oid_t *oid); BSON_EXPORT (uint32_t) bson_oid_hash (const bson_oid_t *oid); BSON_EXPORT (void) bson_oid_init (bson_oid_t *oid, bson_context_t *context); BSON_EXPORT (void) bson_oid_init_from_data (bson_oid_t *oid, const uint8_t *data); BSON_EXPORT (void) bson_oid_init_from_string (bson_oid_t *oid, const char *str); BSON_EXPORT (void) bson_oid_init_sequence (bson_oid_t *oid, bson_context_t *context); BSON_EXPORT (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.3.4/src/libbson/src/bson/bson-private.h0000664000175000017500000000530713210321137021533 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" #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #define BEGIN_IGNORE_DEPRECATIONS \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #define END_IGNORE_DEPRECATIONS _Pragma ("GCC diagnostic pop") #elif defined(__clang__) #define BEGIN_IGNORE_DEPRECATIONS \ _Pragma ("clang diagnostic push") \ _Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"") #define END_IGNORE_DEPRECATIONS _Pragma ("clang diagnostic pop") #else #define BEGIN_IGNORE_DEPRECATIONS #define END_IGNORE_DEPRECATIONS #endif 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; #define BSON_INLINE_DATA_SIZE 120 BSON_ALIGNED_BEGIN (128) typedef struct { bson_flags_t flags; uint32_t len; uint8_t data[BSON_INLINE_DATA_SIZE]; } 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); #define BSON_REGEX_OPTIONS_SORTED "ilmsux" BSON_END_DECLS #endif /* BSON_PRIVATE_H */ mongodb-1.3.4/src/libbson/src/bson/bson-reader.c0000664000175000017500000004602413210321137021317 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 reads 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); } /* *-------------------------------------------------------------------------- * * bson_reader_reset -- * * Restore the reader to its initial state. Valid only for readers * created with bson_reader_new_from_data. * *-------------------------------------------------------------------------- */ void bson_reader_reset (bson_reader_t *reader) { bson_reader_data_t *real = (bson_reader_data_t *) reader; if (real->type != BSON_READER_DATA) { fprintf (stderr, "Reader type cannot be reset\n"); return; } real->offset = 0; } mongodb-1.3.4/src/libbson/src/bson/bson-reader.h0000664000175000017500000000654713210321137021332 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_EXPORT (bson_reader_t *) bson_reader_new_from_handle (void *handle, bson_reader_read_func_t rf, bson_reader_destroy_func_t df); BSON_EXPORT (bson_reader_t *) bson_reader_new_from_fd (int fd, bool close_on_destroy); BSON_EXPORT (bson_reader_t *) bson_reader_new_from_file (const char *path, bson_error_t *error); BSON_EXPORT (bson_reader_t *) bson_reader_new_from_data (const uint8_t *data, size_t length); BSON_EXPORT (void) bson_reader_destroy (bson_reader_t *reader); BSON_EXPORT (void) bson_reader_set_read_func (bson_reader_t *reader, bson_reader_read_func_t func); BSON_EXPORT (void) bson_reader_set_destroy_func (bson_reader_t *reader, bson_reader_destroy_func_t func); BSON_EXPORT (const bson_t *) bson_reader_read (bson_reader_t *reader, bool *reached_eof); BSON_EXPORT (off_t) bson_reader_tell (bson_reader_t *reader); BSON_EXPORT (void) bson_reader_reset (bson_reader_t *reader); BSON_END_DECLS #endif /* BSON_READER_H */ mongodb-1.3.4/src/libbson/src/bson/bson-stdint-win32.h0000664000175000017500000001726113210321137022330 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.3.4/src/libbson/src/bson/bson-stdint.h0000664000175000017500000000112113210321137021354 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.4.0-6ubuntu1~16.04.5) 5.4.0 20160609 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.3.4/src/libbson/src/bson/bson-string.c0000664000175000017500000004144313210321137021363 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-string.h" #include "bson-memory.h" #include "bson-utf8.h" #ifdef HAVE_STRINGS_H #include #else #include #endif /* *-------------------------------------------------------------------------- * * 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); bson_strncpy (ret, str, n_bytes + 1); 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 _MSC_VER 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; } /* *-------------------------------------------------------------------------- * * bson_ascii_strtoll -- * * A portable strtoll. * * Convert a string to a 64-bit signed integer according to the given * @base, which must be 16, 10, or 8. Leading whitespace will be ignored. * * If base is 0 is passed in, the base is inferred from the string's * leading characters. Base-16 numbers start with "0x" or "0X", base-8 * numbers start with "0", base-10 numbers start with a digit from 1 to 9. * * If @e is not NULL, it will be assigned the address of the first invalid * character of @s, or its null terminating byte if the entire string was * valid. * * If an invalid value is encountered, errno will be set to EINVAL and * zero will be returned. If the number is out of range, errno is set to * ERANGE and LLONG_MAX or LLONG_MIN is returned. * * Returns: * The result of the conversion. * * Side effects: * errno will be set on error. * *-------------------------------------------------------------------------- */ int64_t bson_ascii_strtoll (const char *s, char **e, int base) { char *tok = (char *) s; char *digits_start; char c; int64_t number = 0; int64_t sign = 1; int64_t cutoff; int64_t cutlim; errno = 0; if (!s) { errno = EINVAL; return 0; } c = *tok; while (isspace (c)) { c = *++tok; } if (c == '-') { sign = -1; c = *++tok; } else if (c == '+') { c = *++tok; } else if (!isdigit (c)) { errno = EINVAL; return 0; } /* from here down, inspired by NetBSD's strtoll */ if ((base == 0 || base == 16) && c == '0' && (tok[1] == 'x' || tok[1] == 'X')) { tok += 2; c = *tok; base = 16; } if (base == 0) { base = c == '0' ? 8 : 10; } /* Cutoff is the greatest magnitude we'll be able to multiply by base without * range error. If the current number is past cutoff and we see valid digit, * fail. If the number is *equal* to cutoff, then the next digit must be less * than cutlim, otherwise fail. */ cutoff = sign == -1 ? INT64_MIN : INT64_MAX; cutlim = (int) (cutoff % base); cutoff /= base; if (sign == -1) { if (cutlim > 0) { cutlim -= base; cutoff += 1; } cutlim = -cutlim; } digits_start = tok; while ((c = *tok)) { if (isdigit (c)) { c -= '0'; } else if (isalpha (c)) { c -= isupper (c) ? 'A' - 10 : 'a' - 10; } else { /* end of number string */ break; } if (c >= base) { break; } if (sign == -1) { if (number < cutoff || (number == cutoff && c > cutlim)) { number = INT64_MIN; errno = ERANGE; break; } else { number *= base; number -= c; } } else { if (number > cutoff || (number == cutoff && c > cutlim)) { number = INT64_MAX; errno = ERANGE; break; } else { number *= base; number += c; } } tok++; } /* did we parse any digits at all? */ if (e != NULL && tok > digits_start) { *e = tok; } return number; } int bson_strcasecmp (const char *s1, const char *s2) { #ifdef BSON_OS_WIN32 return _stricmp (s1, s2); #else return strcasecmp (s1, s2); #endif } mongodb-1.3.4/src/libbson/src/bson/bson-string.h0000664000175000017500000000463513210321137021372 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_EXPORT (bson_string_t *) bson_string_new (const char *str); BSON_EXPORT (char *) bson_string_free (bson_string_t *string, bool free_segment); BSON_EXPORT (void) bson_string_append (bson_string_t *string, const char *str); BSON_EXPORT (void) bson_string_append_c (bson_string_t *string, char str); BSON_EXPORT (void) bson_string_append_unichar (bson_string_t *string, bson_unichar_t unichar); BSON_EXPORT (void) bson_string_append_printf (bson_string_t *string, const char *format, ...) BSON_GNUC_PRINTF (2, 3); BSON_EXPORT (void) bson_string_truncate (bson_string_t *string, uint32_t len); BSON_EXPORT (char *) bson_strdup (const char *str); BSON_EXPORT (char *) bson_strdup_printf (const char *format, ...) BSON_GNUC_PRINTF (1, 2); BSON_EXPORT (char *) bson_strdupv_printf (const char *format, va_list args) BSON_GNUC_PRINTF (1, 0); BSON_EXPORT (char *) bson_strndup (const char *str, size_t n_bytes); BSON_EXPORT (void) bson_strncpy (char *dst, const char *src, size_t size); BSON_EXPORT (int) bson_vsnprintf (char *str, size_t size, const char *format, va_list ap) BSON_GNUC_PRINTF (3, 0); BSON_EXPORT (int) bson_snprintf (char *str, size_t size, const char *format, ...) BSON_GNUC_PRINTF (3, 4); BSON_EXPORT (void) bson_strfreev (char **strv); BSON_EXPORT (size_t) bson_strnlen (const char *s, size_t maxlen); BSON_EXPORT (int64_t) bson_ascii_strtoll (const char *str, char **endptr, int base); BSON_EXPORT (int) bson_strcasecmp (const char *s1, const char *s2); BSON_END_DECLS #endif /* BSON_STRING_H */ mongodb-1.3.4/src/libbson/src/bson/bson-thread-private.h0000664000175000017500000000455613210321137023005 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.3.4/src/libbson/src/bson/bson-timegm-private.h0000664000175000017500000000273413210321137023014 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 /* avoid system-dependent struct tm definitions */ struct bson_tm { int64_t tm_sec; /* seconds after the minute [0-60] */ int64_t tm_min; /* minutes after the hour [0-59] */ int64_t tm_hour; /* hours since midnight [0-23] */ int64_t tm_mday; /* day of the month [1-31] */ int64_t tm_mon; /* months since January [0-11] */ int64_t tm_year; /* years since 1900 */ int64_t tm_wday; /* days since Sunday [0-6] */ int64_t tm_yday; /* days since January 1 [0-365] */ int64_t tm_isdst; /* Daylight Savings Time flag */ int64_t tm_gmtoff; /* offset from CUT in seconds */ char *tm_zone; /* timezone abbreviation */ }; int64_t _bson_timegm (struct bson_tm *const tmp); BSON_END_DECLS #endif /* BSON_TIMEGM_PRIVATE_H */ mongodb-1.3.4/src/libbson/src/bson/bson-timegm.c0000664000175000017500000005535713210321137021350 0ustar jmikolajmikola/* ** The original version of 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. ** Updated to use int64_t's instead of system-dependent definitions of int64_t ** and struct tm by A. Jesse Jiryu Davis for MongoDB, Inc. */ #include "bson-compat.h" #include "bson-macros.h" #include "bson-timegm-private.h" #include "errno.h" #include "string.h" #include /* for INT64_MAX and INT64_MIN */ /* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned) (c) - '0' <= 9) #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 #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wshift-negative-value" #endif /* The minimum and maximum finite time values. */ static int64_t const time_t_min = INT64_MIN; static int64_t const time_t_max = INT64_MAX; #ifdef __clang__ #pragma clang diagnostic pop #pragma clang diagnostic pop #endif #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; static const char gmt[] = "GMT"; #endif 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 */ int64_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; int64_t ats[TZ_MAX_TIMES]; unsigned char types[TZ_MAX_TIMES]; struct ttinfo ttis[TZ_MAX_TYPES]; char chars[BIGGEST (TZ_MAX_CHARS + 1, (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 bson_tm * gmtsub (const int64_t *timep, int_fast32_t offset, struct bson_tm *tmp); static int64_t increment_overflow (int64_t *number, int64_t delta); static int64_t leaps_thru_end_of (int64_t y) ATTRIBUTE_PURE; static int64_t increment_overflow32 (int_fast32_t *number, int64_t delta); static int64_t normalize_overflow32 (int_fast32_t *tensptr, int64_t *unitsptr, int64_t base); static int64_t normalize_overflow (int64_t *tensptr, int64_t *unitsptr, int64_t base); static int64_t time1 (struct bson_tm *tmp, struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *), int_fast32_t offset); static int64_t time2 (struct bson_tm *tmp, struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *), int_fast32_t offset, int64_t *okayp); static int64_t time2sub (struct bson_tm *tmp, struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *), int_fast32_t offset, int64_t *okayp, int64_t do_norm_secs); static struct bson_tm * timesub (const int64_t *timep, int_fast32_t offset, const struct state *sp, struct bson_tm *tmp); static int64_t tmcomp (const struct bson_tm *atmp, const struct bson_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 bson_tm * gmtsub (const int64_t *const timep, const int_fast32_t offset, struct bson_tm *const tmp) { register struct bson_tm *result; if (!gmt_is_set) { gmt_is_set = true; 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 int64_t leaps_thru_end_of (register const int64_t y) { return (y >= 0) ? (y / 4 - y / 100 + y / 400) : -(leaps_thru_end_of (-(y + 1)) + 1); } static struct bson_tm * timesub (const int64_t *const timep, const int_fast32_t offset, register const struct state *const sp, register struct bson_tm *const tmp) { register const struct lsinfo *lp; register int64_t tdays; register int64_t idays; /* unsigned would be so 2003 */ register int_fast64_t rem; int64_t y; register const int *ip; register int_fast64_t corr; register int64_t hit; register int64_t 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)]) { int64_t newy; register int64_t tdelta; register int64_t idelta; register int64_t leapdays; tdelta = tdays / DAYSPERLYEAR; idelta = 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 -= ((int64_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 = (int64_t) 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 = (int64_t) (rem / SECSPERHOUR); rem %= SECSPERHOUR; tmp->tm_min = (int64_t) (rem / SECSPERMIN); /* ** A positive leap second requires a special ** representation. This uses "... ??:59:60" et seq. */ tmp->tm_sec = (int64_t) (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 = (int64_t) (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 int64_t space. Since int64_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 int64_t increment_overflow (int64_t *const ip, int64_t j) { register int64_t 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 int64_t increment_overflow32 (int_fast32_t *const lp, int64_t 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 int64_t normalize_overflow (int64_t *const tensptr, int64_t *const unitsptr, const int64_t base) { register int64_t tensdelta; tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); *unitsptr -= tensdelta * base; return increment_overflow (tensptr, tensdelta); } static int64_t normalize_overflow32 (int_fast32_t *const tensptr, int64_t *const unitsptr, const int64_t base) { register int64_t tensdelta; tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); *unitsptr -= tensdelta * base; return increment_overflow32 (tensptr, tensdelta); } static int64_t tmcomp (register const struct bson_tm *const atmp, register const struct bson_tm *const btmp) { register int64_t 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 int64_t time2sub (struct bson_tm *const tmp, struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *), const int_fast32_t offset, int64_t *const okayp, const int64_t do_norm_secs) { register const struct state *sp; register int64_t dir; register int64_t i, j; register int64_t saved_seconds; register int_fast32_t li; register int64_t lo; register int64_t hi; int_fast32_t y; int64_t newt; int64_t t; struct bson_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 = (int_fast32_t) 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. */ lo = INT64_MIN; hi = INT64_MAX; 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 bson_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 int64_t time2 (struct bson_tm *const tmp, struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *), const int_fast32_t offset, int64_t *const okayp) { int64_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 int64_t time1 (struct bson_tm *const tmp, struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *), const int_fast32_t offset) { register int64_t t; register const struct state *sp; register int64_t samei, otheri; register int64_t sameind, otherind; register int64_t i; register int64_t nseen; int64_t seen[TZ_MAX_TYPES]; int64_t types[TZ_MAX_TYPES]; int64_t 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; } int64_t _bson_timegm (struct bson_tm *const tmp) { if (tmp != NULL) tmp->tm_isdst = 0; return time1 (tmp, gmtsub, 0L); } mongodb-1.3.4/src/libbson/src/bson/bson-types.h0000664000175000017500000004134713210321137021231 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-config.h" #include "bson-compat.h" #include "bson-endian.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), #ifdef BSON_HAVE_SYSCALL_TID 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_decimal128_t: * * @high The high-order bytes of the decimal128. This field contains sign, * combination bits, exponent, and part of the coefficient continuation. * @low The low-order bytes of the decimal128. This field contains the second * part of the coefficient continuation. * * This structure is a boxed type containing the value for the BSON decimal128 * type. The structure stores the 128 bits such that they correspond to the * native format for the IEEE decimal128 type, if it is implemented. **/ typedef struct { #if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN uint64_t low; uint64_t high; #elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN uint64_t high; uint64_t low; #endif } bson_decimal128_t; /** * 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. * %BSON_VALIDATE_EMPTY_KEYS: Prohibit zero-length field names */ 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_EMPTY_KEYS = (1 << 4), } 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_DECIMAL128 = 0x13, 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; bson_decimal128_t v_decimal128; } 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 { /* run before / after descending into a document */ 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); /* corrupt BSON, or unsupported type and visit_unsupported_type not set */ void (*visit_corrupt) (const bson_iter_t *iter, void *data); /* normal bson field callbacks */ 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); /* normal field with deprecated "Undefined" BSON type */ 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); /* if set, called instead of visit_corrupt when an apparently valid BSON * includes an unrecognized field type (reading future version of BSON) */ void (*visit_unsupported_type) (const bson_iter_t *iter, const char *key, uint32_t type_code, void *data); bool (*visit_decimal128) (const bson_iter_t *iter, const char *key, const bson_decimal128_t *v_decimal128, void *data); void *padding[7]; } bson_visitor_t BSON_ALIGNED_END (8); #define BSON_ERROR_BUFFER_SIZE 504 BSON_ALIGNED_BEGIN (8) typedef struct _bson_error_t { uint32_t domain; uint32_t code; char message[BSON_ERROR_BUFFER_SIZE]; } 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.3.4/src/libbson/src/bson/bson-utf8.c0000664000175000017500000002736013210321137020745 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 '"': 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%04x", (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.3.4/src/libbson/src/bson/bson-utf8.h0000664000175000017500000000237413210321137020750 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 BSON_EXPORT (bool) bson_utf8_validate (const char *utf8, size_t utf8_len, bool allow_null); BSON_EXPORT (char *) bson_utf8_escape_for_json (const char *utf8, ssize_t utf8_len); BSON_EXPORT (bson_unichar_t) bson_utf8_get_char (const char *utf8); BSON_EXPORT (const char *) bson_utf8_next_char (const char *utf8); BSON_EXPORT (void) bson_utf8_from_unichar (bson_unichar_t unichar, char utf8[6], uint32_t *len); BSON_END_DECLS #endif /* BSON_UTF8_H */ mongodb-1.3.4/src/libbson/src/bson/bson-value.c0000664000175000017500000001450513210321137021170 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_DECIMAL128: dst->value.v_decimal128 = src->value.v_decimal128; 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_DECIMAL128: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: case BSON_TYPE_EOD: default: break; } } mongodb-1.3.4/src/libbson/src/bson/bson-value.h0000664000175000017500000000160213210321137021167 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 BSON_EXPORT (void) bson_value_copy (const bson_value_t *src, bson_value_t *dst); BSON_EXPORT (void) bson_value_destroy (bson_value_t *value); BSON_END_DECLS #endif /* BSON_VALUE_H */ mongodb-1.3.4/src/libbson/src/bson/bson-version-functions.c0000664000175000017500000000316613210321137023550 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.3.4/src/libbson/src/bson/bson-version-functions.h0000664000175000017500000000222713210321137023552 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" BSON_BEGIN_DECLS BSON_EXPORT (int) bson_get_major_version (void); BSON_EXPORT (int) bson_get_minor_version (void); BSON_EXPORT (int) bson_get_micro_version (void); BSON_EXPORT (const char *) bson_get_version (void); BSON_EXPORT (bool) bson_check_version (int required_major, int required_minor, int required_micro); BSON_END_DECLS #endif /* BSON_VERSION_FUNCTIONS_H */ mongodb-1.3.4/src/libbson/src/bson/bson-version.h0000664000175000017500000000452113210321137021543 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 (8) /** * BSON_MICRO_VERSION: * * BSON micro version component (e.g. 3 if %BSON_VERSION is 1.2.3) */ #define BSON_MICRO_VERSION (2) /** * 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.8.2) /** * BSON_VERSION_S: * * BSON version, encoded as a string, useful for printing and * concatenation. */ #define BSON_VERSION_S "1.8.2" /** * 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.3.4/src/libbson/src/bson/bson-version.h.in0000664000175000017500000000466513210321137022161 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.3.4/src/libbson/src/bson/bson-writer.c0000664000175000017500000001527613210321137021376 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.3.4/src/libbson/src/bson/bson-writer.h0000664000175000017500000000332713210321137021375 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_EXPORT (bson_writer_t *) bson_writer_new (uint8_t **buf, size_t *buflen, size_t offset, bson_realloc_func realloc_func, void *realloc_func_ctx); BSON_EXPORT (void) bson_writer_destroy (bson_writer_t *writer); BSON_EXPORT (size_t) bson_writer_get_length (bson_writer_t *writer); BSON_EXPORT (bool) bson_writer_begin (bson_writer_t *writer, bson_t **bson); BSON_EXPORT (void) bson_writer_end (bson_writer_t *writer); BSON_EXPORT (void) bson_writer_rollback (bson_writer_t *writer); BSON_END_DECLS #endif /* BSON_WRITER_H */ mongodb-1.3.4/src/libbson/src/bson/bson.c0000664000175000017500000025507213210321137020064 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 "bson-config.h" #include "b64_ntop.h" #include "bson-private.h" #include "bson-string.h" #include "bson-iso8601-private.h" #include #include #ifndef BSON_MAX_RECURSION #define BSON_MAX_RECURSION 200 #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; typedef enum { BSON_JSON_MODE_LEGACY, BSON_JSON_MODE_CANONICAL, BSON_JSON_MODE_RELAXED, } bson_json_mode_t; /* * Structures. */ typedef struct { bson_validate_flags_t flags; ssize_t err_offset; bson_validate_phase_t phase; bson_error_t error; } bson_validate_state_t; typedef struct { uint32_t count; bool keys; ssize_t *err_offset; uint32_t depth; bson_string_t *str; bson_json_mode_t mode; } 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); static char * _bson_as_json_visit_all (const bson_t *bson, size_t *length, bson_json_mode_t mode); /* * 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. * * 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. * * 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 (scope == NULL) { 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_decimal128 (bson_t *bson, const char *key, int key_length, const bson_decimal128_t *value) { static const uint8_t type = BSON_TYPE_DECIMAL128; uint64_t value_le[2]; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (value); if (key_length < 0) { key_length = (int) strlen (key); } value_le[0] = BSON_UINT64_TO_LE (value->low); value_le[1] = BSON_UINT64_TO_LE (value->high); return _bson_append (bson, 4, (1 + key_length + 1 + 16), 1, &type, key_length, key, 1, &gZero, 16, 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_DECIMAL128: { bson_decimal128_t dec; if (!bson_iter_decimal128 (iter, &dec)) { return false; } ret = bson_append_decimal128 (bson, key, key_length, &dec); } 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); } /* *-------------------------------------------------------------------------- * * _bson_append_regex_options_sorted -- * * Helper to append regex options to a buffer in a sorted order. * Any duplicate or unsupported options will be ignored. * * Parameters: * @buffer: Buffer to which sorted options will be appended * @options: Regex options * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE void _bson_append_regex_options_sorted (bson_string_t *buffer, /* IN */ const char *options) /* IN */ { const char *c; for (c = BSON_REGEX_OPTIONS_SORTED; *c; c++) { if (strchr (options, *c)) { bson_string_append_c (buffer, *c); } } } 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; bson_string_t *options_sorted; bool r; 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_sorted = bson_string_new (NULL); _bson_append_regex_options_sorted (options_sorted, options); r = _bson_append (bson, 5, (1 + key_length + 1 + regex_len + options_sorted->len), 1, &type, key_length, key, 1, &gZero, regex_len, regex, options_sorted->len + 1, options_sorted->str); bson_string_free (options_sorted, true); return r; } 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_DECIMAL128: ret = bson_append_decimal128 ( bson, key, key_length, &(value->value.v_decimal128)); 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_t *b; BSON_ASSERT (size <= INT32_MAX); b = bson_malloc (sizeof *b); impl_a = (bson_impl_alloc_t *) b; if (size <= BSON_INLINE_DATA_SIZE) { 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_reserve_buffer (bson_t *bson, uint32_t size) { if (bson->flags & (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) { return NULL; } if (!_bson_grow (bson, size)) { return NULL; } if (bson->flags & BSON_FLAG_INLINE) { /* bson_grow didn't spill over */ ((bson_impl_inline_t *) bson)->len = size; } else { ((bson_impl_alloc_t *) bson)->len = size; } return _bson_data (bson); } bool bson_steal (bson_t *dst, bson_t *src) { bson_impl_inline_t *src_inline; bson_impl_inline_t *dst_inline; bson_impl_alloc_t *alloc; BSON_ASSERT (dst); BSON_ASSERT (src); bson_init (dst); if (src->flags & (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) { return false; } if (src->flags & BSON_FLAG_INLINE) { src_inline = (bson_impl_inline_t *) src; dst_inline = (bson_impl_inline_t *) dst; dst_inline->len = src_inline->len; memcpy (dst_inline->data, src_inline->data, sizeof src_inline->data); /* for consistency, src is always invalid after steal, even if inline */ src->len = 0; } else { memcpy (dst, src, sizeof (bson_t)); alloc = (bson_impl_alloc_t *) dst; alloc->flags |= BSON_FLAG_STATIC; alloc->buf = &alloc->alloc; alloc->buflen = &alloc->alloclen; } if (!(src->flags & BSON_FLAG_STATIC)) { bson_free (src); } else { /* src is invalid after steal */ src->len = 0; } return true; } 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; if (state->mode == BSON_JSON_MODE_CANONICAL) { bson_string_append_printf ( state->str, "{ \"$numberInt\" : \"%" PRId32 "\" }", v_int32); } else { 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; if (state->mode == BSON_JSON_MODE_CANONICAL) { bson_string_append_printf ( state->str, "{ \"$numberLong\" : \"%" PRId64 "\"}", v_int64); } else { bson_string_append_printf (state->str, "%" PRId64, v_int64); } return false; } static bool _bson_as_json_visit_decimal128 (const bson_iter_t *iter, const char *key, const bson_decimal128_t *value, void *data) { bson_json_state_t *state = data; char decimal128_string[BSON_DECIMAL128_STRING]; bson_decimal128_to_string (value, decimal128_string); bson_string_append (state->str, "{ \"$numberDecimal\" : \""); bson_string_append (state->str, decimal128_string); bson_string_append (state->str, "\" }"); 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; bson_string_t *str = state->str; uint32_t start_len; bool legacy; /* Determine if legacy (i.e. unwrapped) output should be used. Relaxed mode * will use this for nan and inf values, which we check manually since old * platforms may not have isinf or isnan. */ legacy = state->mode == BSON_JSON_MODE_LEGACY || (state->mode == BSON_JSON_MODE_RELAXED && !(v_double != v_double || v_double * 0 != 0)); if (!legacy) { bson_string_append (state->str, "{ \"$numberDouble\" : \""); } if (!legacy && v_double != v_double) { bson_string_append (str, "NaN"); } else if (!legacy && v_double * 0 != 0) { if (v_double > 0) { bson_string_append (str, "Infinity"); } else { bson_string_append (str, "-Infinity"); } } else { start_len = str->len; bson_string_append_printf (str, "%.20g", v_double); /* ensure trailing ".0" to distinguish "3" from "3.0" */ if (strspn (&str->str[start_len], "0123456789-") == str->len - start_len) { bson_string_append (str, ".0"); } } if (!legacy) { bson_string_append (state->str, "\" }"); } 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); if (state->mode == BSON_JSON_MODE_CANONICAL || state->mode == BSON_JSON_MODE_RELAXED) { bson_string_append (state->str, "{ \"$binary\" : { \"base64\": \""); bson_string_append (state->str, b64); bson_string_append (state->str, "\", \"subType\" : \""); bson_string_append_printf (state->str, "%02x", v_subtype); bson_string_append (state->str, "\" } }"); } else { bson_string_append (state->str, "{ \"$binary\" : \""); bson_string_append (state->str, b64); bson_string_append (state->str, "\", \"$type\" : \""); bson_string_append_printf (state->str, "%02x", v_subtype); 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; if (state->mode == BSON_JSON_MODE_CANONICAL || (state->mode == BSON_JSON_MODE_RELAXED && msec_since_epoch < 0)) { bson_string_append (state->str, "{ \"$date\" : { \"$numberLong\" : \""); bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch); bson_string_append (state->str, "\" } }"); } else if (state->mode == BSON_JSON_MODE_RELAXED) { bson_string_append (state->str, "{ \"$date\" : \""); _bson_iso8601_date_format (msec_since_epoch, state->str); bson_string_append (state->str, "\" }"); } else { 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; char *escaped; escaped = bson_utf8_escape_for_json (v_regex, -1); if (!escaped) { return true; } if (state->mode == BSON_JSON_MODE_CANONICAL || state->mode == BSON_JSON_MODE_RELAXED) { bson_string_append (state->str, "{ \"$regularExpression\" : { \"pattern\" : \""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\", \"options\" : \""); _bson_append_regex_options_sorted (state->str, v_options); bson_string_append (state->str, "\" } }"); } else { bson_string_append (state->str, "{ \"$regex\" : \""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\", \"$options\" : \""); _bson_append_regex_options_sorted (state->str, v_options); bson_string_append (state->str, "\" }"); } bson_free (escaped); 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 *escaped; char str[25]; escaped = bson_utf8_escape_for_json (v_collection, -1); if (!escaped) { return true; } if (state->mode == BSON_JSON_MODE_CANONICAL || state->mode == BSON_JSON_MODE_RELAXED) { bson_string_append (state->str, "{ \"$dbPointer\" : { \"$ref\" : \""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\""); if (v_oid) { bson_oid_to_string (v_oid, str); bson_string_append (state->str, ", \"$id\" : { \"$oid\" : \""); bson_string_append (state->str, str); bson_string_append (state->str, "\" }"); } bson_string_append (state->str, " } }"); } else { bson_string_append (state->str, "{ \"$ref\" : \""); bson_string_append (state->str, escaped); 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, " }"); } bson_free (escaped); 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 void _bson_as_json_visit_corrupt (const bson_iter_t *iter, void *data) { *(((bson_json_state_t *) data)->err_offset) = iter->off; } 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) { return true; } bson_string_append (state->str, "{ \"$code\" : \""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\" }"); bson_free (escaped); return false; } 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; char *escaped; escaped = bson_utf8_escape_for_json (v_symbol, v_symbol_len); if (!escaped) { return true; } if (state->mode == BSON_JSON_MODE_CANONICAL || state->mode == BSON_JSON_MODE_RELAXED) { bson_string_append (state->str, "{ \"$symbol\" : \""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\" }"); } else { bson_string_append (state->str, "\""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\""); } bson_free (escaped); 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 *code_escaped; char *scope; code_escaped = bson_utf8_escape_for_json (v_code, v_code_len); if (!code_escaped) { return true; } /* Encode scope with the same mode */ scope = _bson_as_json_visit_all (v_scope, NULL, state->mode); if (!scope) { bson_free (code_escaped); return true; } bson_string_append (state->str, "{ \"$code\" : \""); bson_string_append (state->str, code_escaped); bson_string_append (state->str, "\", \"$scope\" : "); bson_string_append (state->str, scope); bson_string_append (state->str, " }"); bson_free (code_escaped); bson_free (scope); return false; } static const bson_visitor_t bson_as_json_visitors = { _bson_as_json_visit_before, NULL, /* visit_after */ _bson_as_json_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, NULL, /* visit_unsupported_type */ _bson_as_json_visit_decimal128, }; 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, state->err_offset}; 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; child_state.mode = state->mode; if (bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state)) { return true; } 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, state->err_offset}; 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; child_state.mode = state->mode; if (bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state)) { return true; } 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 char * _bson_as_json_visit_all (const bson_t *bson, size_t *length, bson_json_mode_t mode) { bson_json_state_t state; bson_iter_t iter; ssize_t err_offset = -1; 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; state.err_offset = &err_offset; state.mode = mode; if (bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) || err_offset != -1) { /* * 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_as_canonical_extended_json (const bson_t *bson, size_t *length) { return _bson_as_json_visit_all (bson, length, BSON_JSON_MODE_CANONICAL); } char * bson_as_json (const bson_t *bson, size_t *length) { return _bson_as_json_visit_all (bson, length, BSON_JSON_MODE_LEGACY); } char * bson_as_relaxed_extended_json (const bson_t *bson, size_t *length) { return _bson_as_json_visit_all (bson, length, BSON_JSON_MODE_RELAXED); } char * bson_array_as_json (const bson_t *bson, size_t *length) { bson_json_state_t state; bson_iter_t iter; ssize_t err_offset = -1; 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; state.err_offset = &err_offset; state.mode = BSON_JSON_MODE_LEGACY; bson_iter_visit_all (&iter, &bson_as_json_visitors, &state); if (bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) || err_offset != -1) { /* * 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); } #define VALIDATION_ERR(_flag, _msg, ...) \ bson_set_error (&state->error, BSON_ERROR_INVALID, _flag, _msg, __VA_ARGS__) 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; VALIDATION_ERR ( BSON_VALIDATE_UTF8, "invalid utf8 string for key \"%s\"", key); 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; VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON"); } 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_EMPTY_KEYS)) { if (key[0] == '\0') { state->err_offset = iter->off; VALIDATION_ERR (BSON_VALIDATE_EMPTY_KEYS, "%s", "empty key"); return true; } } 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; VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS, "keys cannot begin with \"$\": \"%s\"", key); 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; VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS, "invalid key within DBRef subdocument: \"%s\"", key); 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; VALIDATION_ERR ( BSON_VALIDATE_DOT_KEYS, "keys cannot contain \".\": \"%s\"", key); 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 = 0; if (!bson_validate (v_scope, state->flags, &offset)) { state->err_offset = iter->off + offset; VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt code-with-scope"); 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) { if (state->err_offset <= 0) { state->err_offset = iter->off; } return true; } state->phase = phase; return false; } static void _bson_validate_internal (const bson_t *bson, bson_validate_state_t *state) { bson_iter_t iter; state->err_offset = -1; state->phase = BSON_VALIDATE_PHASE_START; memset (&state->error, 0, sizeof state->error); if (!bson_iter_init (&iter, bson)) { state->err_offset = 0; VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON"); } else { _bson_iter_validate_document (&iter, NULL, bson, state); } } bool bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset) { bson_validate_state_t state; state.flags = flags; _bson_validate_internal (bson, &state); if (state.err_offset > 0 && offset) { *offset = (size_t) state.err_offset; } return state.err_offset < 0; } bool bson_validate_with_error (const bson_t *bson, bson_validate_flags_t flags, bson_error_t *error) { bson_validate_state_t state; state.flags = flags; _bson_validate_internal (bson, &state); if (state.err_offset > 0 && error) { memcpy (error, &state.error, sizeof *error); } 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.3.4/src/libbson/src/bson/bson.h0000664000175000017500000007702013210321137020064 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-decimal128.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); * BSON_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_DECIMAL128(b, key, val) \ bson_append_decimal128 (b, key, (int) strlen (key), val) #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_EXPORT (bson_t *) bson_new (void); BSON_EXPORT (bson_t *) bson_new_from_json (const uint8_t *data, ssize_t len, bson_error_t *error); BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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_EXPORT (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. * @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_EXPORT (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_EXPORT (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_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (void) bson_destroy (bson_t *bson); BSON_EXPORT (uint8_t *) bson_reserve_buffer (bson_t *bson, uint32_t size); BSON_EXPORT (bool) bson_steal (bson_t *dst, bson_t *src); /** * bson_destroy_with_steal: * @bson: A #bson_t. * @steal: If ownership of the data buffer should be transferred 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 transferred 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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (bool) bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset); /** * bson_validate_with_error: * @bson: A bson_t. * @error: A location for the error info. * * 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 @error is filled out. */ BSON_EXPORT (bool) bson_validate_with_error (const bson_t *bson, bson_validate_flags_t flags, bson_error_t *error); /** * bson_as_canonical_extended_json: * @bson: A bson_t. * @length: A location for the string length, or NULL. * * Creates a new string containing @bson in canonical extended JSON format, * conforming to the MongoDB Extended JSON Spec: * * github.com/mongodb/specifications/blob/master/source/extended-json.rst * * 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(). */ BSON_EXPORT (char *) bson_as_canonical_extended_json (const bson_t *bson, size_t *length); /** * bson_as_json: * @bson: A bson_t. * @length: A location for the string length, or NULL. * * Creates a new string containing @bson in libbson's legacy JSON format. * Superseded by bson_as_canonical_extended_json and * bson_as_relaxed_extended_json. 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. * * Returns: A newly allocated string that should be freed with bson_free(). */ BSON_EXPORT (char *) bson_as_json (const bson_t *bson, size_t *length); /** * bson_as_relaxed_extended_json: * @bson: A bson_t. * @length: A location for the string length, or NULL. * * Creates a new string containing @bson in relaxed extended JSON format, * conforming to the MongoDB Extended JSON Spec: * * github.com/mongodb/specifications/blob/master/source/extended-json.rst * * 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(). */ BSON_EXPORT (char *) bson_as_relaxed_extended_json (const bson_t *bson, size_t *length); /* like bson_as_json() but for outermost arrays. */ BSON_EXPORT (char *) bson_array_as_json (const bson_t *bson, size_t *length); BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (bool) bson_append_int64 (bson_t *bson, const char *key, int key_length, int64_t value); /** * bson_append_decimal128: * @bson: A bson_t. * @key: The key for the field. * @value: The bson_decimal128_t decimal128 value. * * Appends a new field of type BSON_TYPE_DECIMAL128 to @bson. * * Returns: true if successful; false if append would overflow max size. */ BSON_EXPORT (bool) bson_append_decimal128 (bson_t *bson, const char *key, int key_length, const bson_decimal128_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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (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. */ BSON_EXPORT (bool) bson_append_undefined (bson_t *bson, const char *key, int key_length); BSON_EXPORT (bool) bson_concat (bson_t *dst, const bson_t *src); BSON_END_DECLS #endif /* BSON_H */ mongodb-1.3.4/src/libbson/src/jsonsl/jsonsl.c0000664000175000017500000015020513210321137020772 0ustar jmikolajmikola/* Copyright (C) 2012-2015 Mark Nunberg. * * See included LICENSE file for license details. */ #include "jsonsl.h" #include "bson-memory.h" #include #include #ifdef JSONSL_USE_METRICS #define XMETRICS \ X(STRINGY_INSIGNIFICANT) \ X(STRINGY_SLOWPATH) \ X(ALLOWED_WHITESPACE) \ X(QUOTE_FASTPATH) \ X(SPECIAL_FASTPATH) \ X(SPECIAL_WSPOP) \ X(SPECIAL_SLOWPATH) \ X(GENERIC) \ X(STRUCTURAL_TOKEN) \ X(SPECIAL_SWITCHFIRST) \ X(STRINGY_CATCH) \ X(NUMBER_FASTPATH) \ X(ESCAPES) \ X(TOTAL) \ struct jsonsl_metrics_st { #define X(m) \ unsigned long metric_##m; XMETRICS #undef X }; static struct jsonsl_metrics_st GlobalMetrics = { 0 }; static unsigned long GenericCounter[0x100] = { 0 }; static unsigned long StringyCatchCounter[0x100] = { 0 }; #define INCR_METRIC(m) \ GlobalMetrics.metric_##m++; #define INCR_GENERIC(c) \ INCR_METRIC(GENERIC); \ GenericCounter[c]++; \ #define INCR_STRINGY_CATCH(c) \ INCR_METRIC(STRINGY_CATCH); \ StringyCatchCounter[c]++; JSONSL_API void jsonsl_dump_global_metrics(void) { int ii; printf("JSONSL Metrics:\n"); #define X(m) \ printf("\t%-30s %20lu (%0.2f%%)\n", #m, GlobalMetrics.metric_##m, \ (float)((float)(GlobalMetrics.metric_##m/(float)GlobalMetrics.metric_TOTAL)) * 100); XMETRICS #undef X printf("Generic Characters:\n"); for (ii = 0; ii < 0xff; ii++) { if (GenericCounter[ii]) { printf("\t[ %c ] %lu\n", ii, GenericCounter[ii]); } } printf("Weird string loop\n"); for (ii = 0; ii < 0xff; ii++) { if (StringyCatchCounter[ii]) { printf("\t[ %c ] %lu\n", ii, StringyCatchCounter[ii]); } } } #else #define INCR_METRIC(m) #define INCR_GENERIC(c) #define INCR_STRINGY_CATCH(c) JSONSL_API void jsonsl_dump_global_metrics(void) { } #endif /* JSONSL_USE_METRICS */ #define CASE_DIGITS \ case '1': \ case '2': \ case '3': \ case '4': \ case '5': \ case '6': \ case '7': \ case '8': \ case '9': \ case '0': static unsigned extract_special(unsigned); static int is_special_end(unsigned); static int is_allowed_whitespace(unsigned); static int is_allowed_escape(unsigned); static int is_simple_char(unsigned); static char get_escape_equiv(unsigned); JSONSL_API jsonsl_t jsonsl_new(int nlevels) { unsigned int ii; struct jsonsl_st * jsn; if (nlevels < 2) { return NULL; } jsn = (struct jsonsl_st *) bson_malloc0(sizeof (*jsn) + ( (nlevels-1) * sizeof (struct jsonsl_state_st) ) ); jsn->levels_max = (unsigned int) nlevels; jsn->max_callback_level = UINT_MAX; jsonsl_reset(jsn); for (ii = 0; ii < jsn->levels_max; ii++) { jsn->stack[ii].level = ii; } return jsn; } JSONSL_API void jsonsl_reset(jsonsl_t jsn) { jsn->tok_last = 0; jsn->can_insert = 1; jsn->pos = 0; jsn->level = 0; jsn->stopfl = 0; jsn->in_escape = 0; jsn->expecting = 0; } JSONSL_API void jsonsl_destroy(jsonsl_t jsn) { if (jsn) { bson_free(jsn); } } #define FASTPARSE_EXHAUSTED 1 #define FASTPARSE_BREAK 0 /* * This function is meant to accelerate string parsing, reducing the main loop's * check if we are indeed a string. * * @param jsn the parser * @param[in,out] bytes_p A pointer to the current buffer (i.e. current position) * @param[in,out] nbytes_p A pointer to the current size of the buffer * @return true if all bytes have been exhausted (and thus the main loop can * return), false if a special character was examined which requires greater * examination. */ static int jsonsl__str_fastparse(jsonsl_t jsn, const jsonsl_uchar_t **bytes_p, size_t *nbytes_p) { const jsonsl_uchar_t *bytes = *bytes_p; const jsonsl_uchar_t *end; for (end = bytes + *nbytes_p; bytes != end; bytes++) { if ( #ifdef JSONSL_USE_WCHAR *bytes >= 0x100 || #endif /* JSONSL_USE_WCHAR */ (is_simple_char(*bytes))) { INCR_METRIC(TOTAL); INCR_METRIC(STRINGY_INSIGNIFICANT); } else { /* Once we're done here, re-calculate the position variables */ jsn->pos += (bytes - *bytes_p); *nbytes_p -= (bytes - *bytes_p); *bytes_p = bytes; return FASTPARSE_BREAK; } } /* Once we're done here, re-calculate the position variables */ jsn->pos += (bytes - *bytes_p); return FASTPARSE_EXHAUSTED; } /* Functions exactly like str_fastparse, except it also accepts a 'state' * argument, since the number's value is updated in the state. */ static int jsonsl__num_fastparse(jsonsl_t jsn, const jsonsl_uchar_t **bytes_p, size_t *nbytes_p, struct jsonsl_state_st *state) { int exhausted = 1; size_t nbytes = *nbytes_p; const jsonsl_uchar_t *bytes = *bytes_p; for (; nbytes; nbytes--, bytes++) { jsonsl_uchar_t c = *bytes; if (isdigit(c)) { INCR_METRIC(TOTAL); INCR_METRIC(NUMBER_FASTPATH); state->nelem = (state->nelem * 10) + (c - 0x30); } else { exhausted = 0; break; } } jsn->pos += (*nbytes_p - nbytes); if (exhausted) { return FASTPARSE_EXHAUSTED; } *nbytes_p = nbytes; *bytes_p = bytes; return FASTPARSE_BREAK; } JSONSL_API void jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes) { #define INVOKE_ERROR(eb) \ if (jsn->error_callback(jsn, JSONSL_ERROR_##eb, state, (char*)c)) { \ goto GT_AGAIN; \ } \ return; #define STACK_PUSH \ if (jsn->level >= (levels_max-1)) { \ jsn->error_callback(jsn, JSONSL_ERROR_LEVELS_EXCEEDED, state, (char*)c); \ return; \ } \ state = jsn->stack + (++jsn->level); \ state->ignore_callback = jsn->stack[jsn->level-1].ignore_callback; \ state->pos_begin = jsn->pos; #define STACK_POP_NOPOS \ state->pos_cur = jsn->pos; \ state = jsn->stack + (--jsn->level); #define STACK_POP \ STACK_POP_NOPOS; \ state->pos_cur = jsn->pos; #define CALLBACK_AND_POP_NOPOS(T) \ state->pos_cur = jsn->pos; \ DO_CALLBACK(T, POP); \ state->nescapes = 0; \ state = jsn->stack + (--jsn->level); #define CALLBACK_AND_POP(T) \ CALLBACK_AND_POP_NOPOS(T); \ state->pos_cur = jsn->pos; #define SPECIAL_POP \ CALLBACK_AND_POP(SPECIAL); \ jsn->expecting = 0; \ jsn->tok_last = 0; \ #define CUR_CHAR (*(jsonsl_uchar_t*)c) #define DO_CALLBACK(T, action) \ if (jsn->call_##T && \ jsn->max_callback_level > state->level && \ state->ignore_callback == 0) { \ \ if (jsn->action_callback_##action) { \ jsn->action_callback_##action(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \ } else if (jsn->action_callback) { \ jsn->action_callback(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \ } \ if (jsn->stopfl) { return; } \ } /** * Verifies that we are able to insert the (non-string) item into a hash. */ #define ENSURE_HVAL \ if (state->nelem % 2 == 0 && state->type == JSONSL_T_OBJECT) { \ INVOKE_ERROR(HKEY_EXPECTED); \ } #define VERIFY_SPECIAL(lit) \ if (CUR_CHAR != (lit)[jsn->pos - state->pos_begin]) { \ INVOKE_ERROR(SPECIAL_EXPECTED); \ } #define VERIFY_SPECIAL_CI(lit) \ if (tolower(CUR_CHAR) != (lit)[jsn->pos - state->pos_begin]) { \ INVOKE_ERROR(SPECIAL_EXPECTED); \ } #define STATE_SPECIAL_LENGTH \ (state)->nescapes #define IS_NORMAL_NUMBER \ ((state)->special_flags == JSONSL_SPECIALf_UNSIGNED || \ (state)->special_flags == JSONSL_SPECIALf_SIGNED) #define STATE_NUM_LAST jsn->tok_last #define CONTINUE_NEXT_CHAR() continue const jsonsl_uchar_t *c = (jsonsl_uchar_t*)bytes; size_t levels_max = jsn->levels_max; struct jsonsl_state_st *state = jsn->stack + jsn->level; jsn->base = bytes; for (; nbytes; nbytes--, jsn->pos++, c++) { unsigned state_type; INCR_METRIC(TOTAL); GT_AGAIN: state_type = state->type; /* Most common type is typically a string: */ if (state_type & JSONSL_Tf_STRINGY) { /* Special escape handling for some stuff */ if (jsn->in_escape) { jsn->in_escape = 0; if (!is_allowed_escape(CUR_CHAR)) { INVOKE_ERROR(ESCAPE_INVALID); } else if (CUR_CHAR == 'u') { DO_CALLBACK(UESCAPE, UESCAPE); if (jsn->return_UESCAPE) { return; } } CONTINUE_NEXT_CHAR(); } if (jsonsl__str_fastparse(jsn, &c, &nbytes) == FASTPARSE_EXHAUSTED) { /* No need to readjust variables as we've exhausted the iterator */ return; } else { if (CUR_CHAR == '"') { goto GT_QUOTE; } else if (CUR_CHAR == '\\') { goto GT_ESCAPE; } else { INVOKE_ERROR(WEIRD_WHITESPACE); } } INCR_METRIC(STRINGY_SLOWPATH); } else if (state_type == JSONSL_T_SPECIAL) { /* Fast track for signed/unsigned */ if (IS_NORMAL_NUMBER) { if (jsonsl__num_fastparse(jsn, &c, &nbytes, state) == FASTPARSE_EXHAUSTED) { return; } else { goto GT_SPECIAL_NUMERIC; } } else if (state->special_flags == JSONSL_SPECIALf_DASH) { #ifdef JSONSL_PARSE_NAN if (CUR_CHAR == 'I' || CUR_CHAR == 'i') { /* parsing -Infinity? */ state->special_flags = JSONSL_SPECIALf_NEG_INF; CONTINUE_NEXT_CHAR(); } #endif if (!isdigit(CUR_CHAR)) { INVOKE_ERROR(INVALID_NUMBER); } if (CUR_CHAR == '0') { state->special_flags = JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED; } else if (isdigit(CUR_CHAR)) { state->special_flags = JSONSL_SPECIALf_SIGNED; state->nelem = CUR_CHAR - 0x30; } else { INVOKE_ERROR(INVALID_NUMBER); } CONTINUE_NEXT_CHAR(); } else if (state->special_flags == JSONSL_SPECIALf_ZERO) { if (isdigit(CUR_CHAR)) { /* Following a zero! */ INVOKE_ERROR(INVALID_NUMBER); } /* Unset the 'zero' flag: */ if (state->special_flags & JSONSL_SPECIALf_SIGNED) { state->special_flags = JSONSL_SPECIALf_SIGNED; } else { state->special_flags = JSONSL_SPECIALf_UNSIGNED; } goto GT_SPECIAL_NUMERIC; } if ((state->special_flags & JSONSL_SPECIALf_NUMERIC) && !(state->special_flags & JSONSL_SPECIALf_INF)) { GT_SPECIAL_NUMERIC: switch (CUR_CHAR) { CASE_DIGITS STATE_NUM_LAST = '1'; CONTINUE_NEXT_CHAR(); case '.': if (state->special_flags & JSONSL_SPECIALf_FLOAT) { INVOKE_ERROR(INVALID_NUMBER); } state->special_flags |= JSONSL_SPECIALf_FLOAT; STATE_NUM_LAST = '.'; CONTINUE_NEXT_CHAR(); case 'e': case 'E': if (state->special_flags & JSONSL_SPECIALf_EXPONENT) { INVOKE_ERROR(INVALID_NUMBER); } state->special_flags |= JSONSL_SPECIALf_EXPONENT; STATE_NUM_LAST = 'e'; CONTINUE_NEXT_CHAR(); case '-': case '+': if (STATE_NUM_LAST != 'e') { INVOKE_ERROR(INVALID_NUMBER); } STATE_NUM_LAST = '-'; CONTINUE_NEXT_CHAR(); default: if (is_special_end(CUR_CHAR)) { goto GT_SPECIAL_POP; } INVOKE_ERROR(INVALID_NUMBER); break; } } /* else if (!NUMERIC) */ if (!is_special_end(CUR_CHAR)) { STATE_SPECIAL_LENGTH++; /* Verify TRUE, FALSE, NULL */ if (state->special_flags == JSONSL_SPECIALf_TRUE) { VERIFY_SPECIAL("true"); } else if (state->special_flags == JSONSL_SPECIALf_FALSE) { VERIFY_SPECIAL("false"); } else if (state->special_flags == JSONSL_SPECIALf_NULL) { VERIFY_SPECIAL("null"); #ifdef JSONSL_PARSE_NAN } else if (state->special_flags == JSONSL_SPECIALf_POS_INF) { VERIFY_SPECIAL_CI("infinity"); } else if (state->special_flags == JSONSL_SPECIALf_NEG_INF) { VERIFY_SPECIAL_CI("-infinity"); } else if (state->special_flags == JSONSL_SPECIALf_NAN) { VERIFY_SPECIAL_CI("nan"); } else if (state->special_flags & JSONSL_SPECIALf_NULL || state->special_flags & JSONSL_SPECIALf_NAN) { /* previous char was "n", are we parsing null or nan? */ if (CUR_CHAR != 'u') { state->special_flags &= ~JSONSL_SPECIALf_NULL; } if (tolower(CUR_CHAR) != 'a') { state->special_flags &= ~JSONSL_SPECIALf_NAN; } #endif } INCR_METRIC(SPECIAL_FASTPATH); CONTINUE_NEXT_CHAR(); } GT_SPECIAL_POP: jsn->can_insert = 0; if (IS_NORMAL_NUMBER) { /* Nothing */ } else if (state->special_flags == JSONSL_SPECIALf_ZERO || state->special_flags == (JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED)) { /* 0 is unsigned! */ state->special_flags = JSONSL_SPECIALf_UNSIGNED; } else if (state->special_flags == JSONSL_SPECIALf_DASH) { /* Still in dash! */ INVOKE_ERROR(INVALID_NUMBER); } else if (state->special_flags & JSONSL_SPECIALf_INF) { if (STATE_SPECIAL_LENGTH != 8) { INVOKE_ERROR(SPECIAL_INCOMPLETE); } state->nelem = 1; } else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) { /* Check that we're not at the end of a token */ if (STATE_NUM_LAST != '1') { INVOKE_ERROR(INVALID_NUMBER); } } else if (state->special_flags == JSONSL_SPECIALf_TRUE) { if (STATE_SPECIAL_LENGTH != 4) { INVOKE_ERROR(SPECIAL_INCOMPLETE); } state->nelem = 1; } else if (state->special_flags == JSONSL_SPECIALf_FALSE) { if (STATE_SPECIAL_LENGTH != 5) { INVOKE_ERROR(SPECIAL_INCOMPLETE); } } else if (state->special_flags == JSONSL_SPECIALf_NULL) { if (STATE_SPECIAL_LENGTH != 4) { INVOKE_ERROR(SPECIAL_INCOMPLETE); } } SPECIAL_POP; jsn->expecting = ','; if (is_allowed_whitespace(CUR_CHAR)) { CONTINUE_NEXT_CHAR(); } /** * This works because we have a non-whitespace token * which is not a special token. If this is a structural * character then it will be gracefully handled by the * switch statement. Otherwise it will default to the 'special' * state again, */ goto GT_STRUCTURAL_TOKEN; } else if (is_allowed_whitespace(CUR_CHAR)) { INCR_METRIC(ALLOWED_WHITESPACE); /* So we're not special. Harmless insignificant whitespace * passthrough */ CONTINUE_NEXT_CHAR(); } else if (extract_special(CUR_CHAR)) { /* not a string, whitespace, or structural token. must be special */ goto GT_SPECIAL_BEGIN; } INCR_GENERIC(CUR_CHAR); if (CUR_CHAR == '"') { GT_QUOTE: jsn->can_insert = 0; switch (state_type) { /* the end of a string or hash key */ case JSONSL_T_STRING: CALLBACK_AND_POP(STRING); CONTINUE_NEXT_CHAR(); case JSONSL_T_HKEY: CALLBACK_AND_POP(HKEY); CONTINUE_NEXT_CHAR(); case JSONSL_T_OBJECT: state->nelem++; if ( (state->nelem-1) % 2 ) { /* Odd, this must be a hash value */ if (jsn->tok_last != ':') { INVOKE_ERROR(MISSING_TOKEN); } jsn->expecting = ','; /* Can't figure out what to expect next */ jsn->tok_last = 0; STACK_PUSH; state->type = JSONSL_T_STRING; DO_CALLBACK(STRING, PUSH); } else { /* hash key */ if (jsn->expecting != '"') { INVOKE_ERROR(STRAY_TOKEN); } jsn->tok_last = 0; jsn->expecting = ':'; STACK_PUSH; state->type = JSONSL_T_HKEY; DO_CALLBACK(HKEY, PUSH); } CONTINUE_NEXT_CHAR(); case JSONSL_T_LIST: state->nelem++; STACK_PUSH; state->type = JSONSL_T_STRING; jsn->expecting = ','; jsn->tok_last = 0; DO_CALLBACK(STRING, PUSH); CONTINUE_NEXT_CHAR(); case JSONSL_T_SPECIAL: INVOKE_ERROR(STRAY_TOKEN); break; default: INVOKE_ERROR(STRING_OUTSIDE_CONTAINER); break; } /* switch(state->type) */ } else if (CUR_CHAR == '\\') { GT_ESCAPE: INCR_METRIC(ESCAPES); /* Escape */ if ( (state->type & JSONSL_Tf_STRINGY) == 0 ) { INVOKE_ERROR(ESCAPE_OUTSIDE_STRING); } state->nescapes++; jsn->in_escape = 1; CONTINUE_NEXT_CHAR(); } /* " or \ */ GT_STRUCTURAL_TOKEN: switch (CUR_CHAR) { case ':': INCR_METRIC(STRUCTURAL_TOKEN); if (jsn->expecting != CUR_CHAR) { INVOKE_ERROR(STRAY_TOKEN); } jsn->tok_last = ':'; jsn->can_insert = 1; jsn->expecting = '"'; CONTINUE_NEXT_CHAR(); case ',': INCR_METRIC(STRUCTURAL_TOKEN); /** * The comma is one of the more generic tokens. * In the context of an OBJECT, the can_insert flag * should never be set, and no other action is * necessary. */ if (jsn->expecting != CUR_CHAR) { /* make this branch execute only when we haven't manually * just placed the ',' in the expecting register. */ INVOKE_ERROR(STRAY_TOKEN); } if (state->type == JSONSL_T_OBJECT) { /* end of hash value, expect a string as a hash key */ jsn->expecting = '"'; } else { jsn->can_insert = 1; } jsn->tok_last = ','; jsn->expecting = '"'; CONTINUE_NEXT_CHAR(); /* new list or object */ /* hashes are more common */ case '{': case '[': INCR_METRIC(STRUCTURAL_TOKEN); if (!jsn->can_insert) { INVOKE_ERROR(CANT_INSERT); } ENSURE_HVAL; state->nelem++; STACK_PUSH; /* because the constants match the opening delimiters, we can do this: */ state->type = CUR_CHAR; state->nelem = 0; jsn->can_insert = 1; if (CUR_CHAR == '{') { /* If we're a hash, we expect a key first, which is quouted */ jsn->expecting = '"'; } if (CUR_CHAR == JSONSL_T_OBJECT) { DO_CALLBACK(OBJECT, PUSH); } else { DO_CALLBACK(LIST, PUSH); } jsn->tok_last = 0; CONTINUE_NEXT_CHAR(); /* closing of list or object */ case '}': case ']': INCR_METRIC(STRUCTURAL_TOKEN); if (jsn->tok_last == ',' && jsn->options.allow_trailing_comma == 0) { INVOKE_ERROR(TRAILING_COMMA); } jsn->can_insert = 0; jsn->level--; jsn->expecting = ','; jsn->tok_last = 0; if (CUR_CHAR == ']') { if (state->type != '[') { INVOKE_ERROR(BRACKET_MISMATCH); } DO_CALLBACK(LIST, POP); } else { if (state->type != '{') { INVOKE_ERROR(BRACKET_MISMATCH); } else if (state->nelem && state->nelem % 2 != 0) { INVOKE_ERROR(VALUE_EXPECTED); } DO_CALLBACK(OBJECT, POP); } state = jsn->stack + jsn->level; state->pos_cur = jsn->pos; CONTINUE_NEXT_CHAR(); default: GT_SPECIAL_BEGIN: /** * Not a string, not a structural token, and not benign whitespace. * Technically we should iterate over the character always, but since * we are not doing full numerical/value decoding anyway (but only hinting), * we only check upon entry. */ if (state->type != JSONSL_T_SPECIAL) { int special_flags = extract_special(CUR_CHAR); if (!special_flags) { /** * Try to do some heuristics here anyway to figure out what kind of * error this is. The 'special' case is a fallback scenario anyway. */ if (CUR_CHAR == '\0') { INVOKE_ERROR(FOUND_NULL_BYTE); } else if (CUR_CHAR < 0x20) { INVOKE_ERROR(WEIRD_WHITESPACE); } else { INVOKE_ERROR(SPECIAL_EXPECTED); } } ENSURE_HVAL; state->nelem++; if (!jsn->can_insert) { INVOKE_ERROR(CANT_INSERT); } STACK_PUSH; state->type = JSONSL_T_SPECIAL; state->special_flags = special_flags; STATE_SPECIAL_LENGTH = 1; if (special_flags == JSONSL_SPECIALf_UNSIGNED) { state->nelem = CUR_CHAR - 0x30; STATE_NUM_LAST = '1'; } else { STATE_NUM_LAST = '-'; state->nelem = 0; } DO_CALLBACK(SPECIAL, PUSH); } CONTINUE_NEXT_CHAR(); } } } JSONSL_API const char* jsonsl_strerror(jsonsl_error_t err) { if (err == JSONSL_ERROR_SUCCESS) { return "SUCCESS"; } #define X(t) \ if (err == JSONSL_ERROR_##t) \ return #t; JSONSL_XERR; #undef X return ""; } JSONSL_API const char *jsonsl_strtype(jsonsl_type_t type) { #define X(o,c) \ if (type == JSONSL_T_##o) \ return #o; JSONSL_XTYPE #undef X return "UNKNOWN TYPE"; } /* * * JPR/JSONPointer functions * * */ #ifndef JSONSL_NO_JPR static jsonsl_jpr_type_t populate_component(char *in, struct jsonsl_jpr_component_st *component, char **next, jsonsl_error_t *errp) { unsigned long pctval; char *c = NULL, *outp = NULL, *end = NULL; size_t input_len; jsonsl_jpr_type_t ret = JSONSL_PATH_NONE; if (*next == NULL || *(*next) == '\0') { return JSONSL_PATH_NONE; } /* Replace the next / with a NULL */ *next = strstr(in, "/"); if (*next != NULL) { *(*next) = '\0'; /* drop the forward slash */ input_len = *next - in; end = *next; *next += 1; /* next character after the '/' */ } else { input_len = strlen(in); end = in + input_len + 1; } component->pstr = in; /* Check for special components of interest */ if (*in == JSONSL_PATH_WILDCARD_CHAR && input_len == 1) { /* Lone wildcard */ ret = JSONSL_PATH_WILDCARD; goto GT_RET; } else if (isdigit(*in)) { /* ASCII Numeric */ char *endptr; component->idx = strtoul(in, &endptr, 10); if (endptr && *endptr == '\0') { ret = JSONSL_PATH_NUMERIC; goto GT_RET; } } /* Default, it's a string */ ret = JSONSL_PATH_STRING; for (c = outp = in; c < end; c++, outp++) { char origc; if (*c != '%') { goto GT_ASSIGN; } /* * c = { [+0] = '%', [+1] = 'b', [+2] = 'e', [+3] = '\0' } */ /* Need %XX */ if (c+2 >= end) { *errp = JSONSL_ERROR_PERCENT_BADHEX; return JSONSL_PATH_INVALID; } if (! (isxdigit(*(c+1)) && isxdigit(*(c+2))) ) { *errp = JSONSL_ERROR_PERCENT_BADHEX; return JSONSL_PATH_INVALID; } /* Temporarily null-terminate the characters */ origc = *(c+3); *(c+3) = '\0'; pctval = strtoul(c+1, NULL, 16); *(c+3) = origc; *outp = (char) pctval; c += 2; continue; GT_ASSIGN: *outp = *c; } /* Null-terminate the string */ for (; outp < c; outp++) { *outp = '\0'; } GT_RET: component->ptype = ret; if (ret != JSONSL_PATH_WILDCARD) { component->len = strlen(component->pstr); } return ret; } JSONSL_API jsonsl_jpr_t jsonsl_jpr_new(const char *path, jsonsl_error_t *errp) { char *my_copy = NULL; int count, curidx; struct jsonsl_jpr_st *ret = NULL; struct jsonsl_jpr_component_st *components = NULL; size_t origlen; jsonsl_error_t errstacked; #define JPR_BAIL(err) *errp = err; goto GT_ERROR; if (errp == NULL) { errp = &errstacked; } if (path == NULL || *path != '/') { JPR_BAIL(JSONSL_ERROR_JPR_NOROOT); } count = 1; path++; { const char *c = path; for (; *c; c++) { if (*c == '/') { count++; if (*(c+1) == '/') { JPR_BAIL(JSONSL_ERROR_JPR_DUPSLASH); } } } } if(*path) { count++; } components = (struct jsonsl_jpr_component_st *) malloc(sizeof(*components) * count); if (!components) { JPR_BAIL(JSONSL_ERROR_ENOMEM); } my_copy = (char *)malloc(strlen(path) + 1); if (!my_copy) { JPR_BAIL(JSONSL_ERROR_ENOMEM); } strcpy(my_copy, path); components[0].ptype = JSONSL_PATH_ROOT; if (*my_copy) { char *cur = my_copy; int pathret = JSONSL_PATH_STRING; curidx = 1; while (curidx < count) { pathret = populate_component(cur, components + curidx, &cur, errp); if (pathret > 0) { curidx++; } else { break; } } if (pathret == JSONSL_PATH_INVALID) { JPR_BAIL(JSONSL_ERROR_JPR_BADPATH); } } else { curidx = 1; } path--; /*revert path to leading '/' */ origlen = strlen(path) + 1; ret = (struct jsonsl_jpr_st *)malloc(sizeof(*ret)); if (!ret) { JPR_BAIL(JSONSL_ERROR_ENOMEM); } ret->orig = (char *)malloc(origlen); if (!ret->orig) { JPR_BAIL(JSONSL_ERROR_ENOMEM); } ret->components = components; ret->ncomponents = curidx; ret->basestr = my_copy; ret->norig = origlen-1; strcpy(ret->orig, path); return ret; GT_ERROR: free(my_copy); free(components); if (ret) { free(ret->orig); } free(ret); return NULL; #undef JPR_BAIL } void jsonsl_jpr_destroy(jsonsl_jpr_t jpr) { free(jpr->components); free(jpr->basestr); free(jpr->orig); free(jpr); } /** * Call when there is a possibility of a match, either as a final match or * as a path within a match * @param jpr The JPR path * @param component Component corresponding to the current element * @param prlevel The level of the *parent* * @param chtype The type of the child * @return Match status */ static jsonsl_jpr_match_t jsonsl__match_continue(jsonsl_jpr_t jpr, const struct jsonsl_jpr_component_st *component, unsigned prlevel, unsigned chtype) { const struct jsonsl_jpr_component_st *next_comp = component + 1; if (prlevel == jpr->ncomponents - 1) { /* This is the match. Check the expected type of the match against * the child */ if (jpr->match_type == 0 || jpr->match_type == chtype) { return JSONSL_MATCH_COMPLETE; } else { return JSONSL_MATCH_TYPE_MISMATCH; } } if (chtype == JSONSL_T_LIST) { if (next_comp->ptype == JSONSL_PATH_NUMERIC) { return JSONSL_MATCH_POSSIBLE; } else { return JSONSL_MATCH_TYPE_MISMATCH; } } else if (chtype == JSONSL_T_OBJECT) { if (next_comp->ptype == JSONSL_PATH_NUMERIC) { return JSONSL_MATCH_TYPE_MISMATCH; } else { return JSONSL_MATCH_POSSIBLE; } } else { return JSONSL_MATCH_TYPE_MISMATCH; } } JSONSL_API jsonsl_jpr_match_t jsonsl_path_match(jsonsl_jpr_t jpr, const struct jsonsl_state_st *parent, const struct jsonsl_state_st *child, const char *key, size_t nkey) { const struct jsonsl_jpr_component_st *comp; if (!parent) { /* No parent. Return immediately since it's always a match */ return jsonsl__match_continue(jpr, jpr->components, 0, child->type); } comp = jpr->components + parent->level; /* note that we don't need to verify the type of the match, this is * always done through the previous call to jsonsl__match_continue. * If we are in a POSSIBLE tree then we can be certain the types (at * least at this level) are correct */ if (parent->type == JSONSL_T_OBJECT) { if (comp->len != nkey || strncmp(key, comp->pstr, nkey) != 0) { return JSONSL_MATCH_NOMATCH; } } else { if (comp->idx != parent->nelem - 1) { return JSONSL_MATCH_NOMATCH; } } return jsonsl__match_continue(jpr, comp, parent->level, child->type); } JSONSL_API jsonsl_jpr_match_t jsonsl_jpr_match(jsonsl_jpr_t jpr, unsigned int parent_type, unsigned int parent_level, const char *key, size_t nkey) { /* find our current component. This is the child level */ int cmpret; struct jsonsl_jpr_component_st *p_component; p_component = jpr->components + parent_level; if (parent_level >= jpr->ncomponents) { return JSONSL_MATCH_NOMATCH; } /* Lone query for 'root' element. Always matches */ if (parent_level == 0) { if (jpr->ncomponents == 1) { return JSONSL_MATCH_COMPLETE; } else { return JSONSL_MATCH_POSSIBLE; } } /* Wildcard, always matches */ if (p_component->ptype == JSONSL_PATH_WILDCARD) { if (parent_level == jpr->ncomponents-1) { return JSONSL_MATCH_COMPLETE; } else { return JSONSL_MATCH_POSSIBLE; } } /* Check numeric array index. This gets its special block so we can avoid * string comparisons */ if (p_component->ptype == JSONSL_PATH_NUMERIC) { if (parent_type == JSONSL_T_LIST) { if (p_component->idx != nkey) { /* Wrong index */ return JSONSL_MATCH_NOMATCH; } else { if (parent_level == jpr->ncomponents-1) { /* This is the last element of the path */ return JSONSL_MATCH_COMPLETE; } else { /* Intermediate element */ return JSONSL_MATCH_POSSIBLE; } } } else if (p_component->is_arridx) { /* Numeric and an array index (set explicitly by user). But not * a list for a parent */ return JSONSL_MATCH_TYPE_MISMATCH; } } else if (parent_type == JSONSL_T_LIST) { return JSONSL_MATCH_TYPE_MISMATCH; } /* Check lengths */ if (p_component->len != nkey) { return JSONSL_MATCH_NOMATCH; } /* Check string comparison */ cmpret = strncmp(p_component->pstr, key, nkey); if (cmpret == 0) { if (parent_level == jpr->ncomponents-1) { return JSONSL_MATCH_COMPLETE; } else { return JSONSL_MATCH_POSSIBLE; } } return JSONSL_MATCH_NOMATCH; } JSONSL_API void jsonsl_jpr_match_state_init(jsonsl_t jsn, jsonsl_jpr_t *jprs, size_t njprs) { size_t ii, *firstjmp; if (njprs == 0) { return; } jsn->jprs = (jsonsl_jpr_t *)malloc(sizeof(jsonsl_jpr_t) * njprs); jsn->jpr_count = njprs; jsn->jpr_root = (size_t*)calloc(1, sizeof(size_t) * njprs * jsn->levels_max); memcpy(jsn->jprs, jprs, sizeof(jsonsl_jpr_t) * njprs); /* Set the initial jump table values */ firstjmp = jsn->jpr_root; for (ii = 0; ii < njprs; ii++) { firstjmp[ii] = ii+1; } } JSONSL_API void jsonsl_jpr_match_state_cleanup(jsonsl_t jsn) { if (jsn->jpr_count == 0) { return; } free(jsn->jpr_root); free(jsn->jprs); jsn->jprs = NULL; jsn->jpr_root = NULL; jsn->jpr_count = 0; } /** * This function should be called exactly once on each element... * This should also be called in recursive order, since we rely * on the parent having been initalized for a match. * * Since the parent is checked for a match as well, we maintain a 'serial' counter. * Whenever we traverse an element, we expect the serial to be the same as a global * integer. If they do not match, we re-initialize the context, and set the serial. * * This ensures a type of consistency without having a proactive reset by the * main lexer itself. * */ JSONSL_API jsonsl_jpr_t jsonsl_jpr_match_state(jsonsl_t jsn, struct jsonsl_state_st *state, const char *key, size_t nkey, jsonsl_jpr_match_t *out) { struct jsonsl_state_st *parent_state; jsonsl_jpr_t ret = NULL; /* Jump and JPR tables for our own state and the parent state */ size_t *jmptable, *pjmptable; size_t jmp_cur, ii, ourjmpidx; if (!jsn->jpr_root) { *out = JSONSL_MATCH_NOMATCH; return NULL; } pjmptable = jsn->jpr_root + (jsn->jpr_count * (state->level-1)); jmptable = pjmptable + jsn->jpr_count; /* If the parent cannot match, then invalidate it */ if (*pjmptable == 0) { *jmptable = 0; *out = JSONSL_MATCH_NOMATCH; return NULL; } parent_state = jsn->stack + state->level - 1; if (parent_state->type == JSONSL_T_LIST) { nkey = (size_t) parent_state->nelem; } *jmptable = 0; ourjmpidx = 0; memset(jmptable, 0, sizeof(int) * jsn->jpr_count); for (ii = 0; ii < jsn->jpr_count; ii++) { jmp_cur = pjmptable[ii]; if (jmp_cur) { jsonsl_jpr_t jpr = jsn->jprs[jmp_cur-1]; *out = jsonsl_jpr_match(jpr, parent_state->type, parent_state->level, key, nkey); if (*out == JSONSL_MATCH_COMPLETE) { ret = jpr; *jmptable = 0; return ret; } else if (*out == JSONSL_MATCH_POSSIBLE) { jmptable[ourjmpidx] = ii+1; ourjmpidx++; } } else { break; } } if (!*jmptable) { *out = JSONSL_MATCH_NOMATCH; } return NULL; } JSONSL_API const char *jsonsl_strmatchtype(jsonsl_jpr_match_t match) { #define X(T,v) \ if ( match == JSONSL_MATCH_##T ) \ return #T; JSONSL_XMATCH #undef X return ""; } #endif /* JSONSL_WITH_JPR */ static char * jsonsl__writeutf8(uint32_t pt, char *out) { #define ADD_OUTPUT(c) *out = (char)(c); out++; if (pt < 0x80) { ADD_OUTPUT(pt); } else if (pt < 0x800) { ADD_OUTPUT((pt >> 6) | 0xC0); ADD_OUTPUT((pt & 0x3F) | 0x80); } else if (pt < 0x10000) { ADD_OUTPUT((pt >> 12) | 0xE0); ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80); ADD_OUTPUT((pt & 0x3F) | 0x80); } else { ADD_OUTPUT((pt >> 18) | 0xF0); ADD_OUTPUT(((pt >> 12) & 0x3F) | 0x80); ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80); ADD_OUTPUT((pt & 0x3F) | 0x80); } return out; #undef ADD_OUTPUT } /* Thanks snej (https://github.com/mnunberg/jsonsl/issues/9) */ static int jsonsl__digit2int(char ch) { int d = ch - '0'; if ((unsigned) d < 10) { return d; } d = ch - 'a'; if ((unsigned) d < 6) { return d + 10; } d = ch - 'A'; if ((unsigned) d < 6) { return d + 10; } return -1; } /* Assume 's' is at least 4 bytes long */ static int jsonsl__get_uescape_16(const char *s) { int ret = 0; int cur; #define GET_DIGIT(off) \ cur = jsonsl__digit2int(s[off]); \ if (cur == -1) { return -1; } \ ret |= (cur << (12 - (off * 4))); GET_DIGIT(0); GET_DIGIT(1); GET_DIGIT(2); GET_DIGIT(3); #undef GET_DIGIT return ret; } /** * Utility function to convert escape sequences */ JSONSL_API size_t jsonsl_util_unescape_ex(const char *in, char *out, size_t len, const int toEscape[128], unsigned *oflags, jsonsl_error_t *err, const char **errat) { const unsigned char *c = (const unsigned char*)in; char *begin_p = out; unsigned oflags_s; uint16_t last_codepoint = 0; if (!oflags) { oflags = &oflags_s; } *oflags = 0; #define UNESCAPE_BAIL(e,offset) \ *err = JSONSL_ERROR_##e; \ if (errat) { \ *errat = (const char*)(c+ (ptrdiff_t)(offset)); \ } \ return 0; for (; len; len--, c++, out++) { int uescval; if (*c != '\\') { /* Not an escape, so we don't care about this */ goto GT_ASSIGN; } if (len < 2) { UNESCAPE_BAIL(ESCAPE_INVALID, 0); } if (!is_allowed_escape(c[1])) { UNESCAPE_BAIL(ESCAPE_INVALID, 1) } if ((toEscape && toEscape[(unsigned char)c[1] & 0x7f] == 0 && c[1] != '\\' && c[1] != '"')) { /* if we don't want to unescape this string, write the escape sequence to the output */ *out++ = *c++; --len; goto GT_ASSIGN; } if (c[1] != 'u') { /* simple skip-and-replace using pre-defined maps. * TODO: should the maps actually reflect the desired * replacement character in toEscape? */ char esctmp = get_escape_equiv(c[1]); if (esctmp) { /* Check if there is a corresponding replacement */ *out = esctmp; } else { /* Just gobble up the 'reverse-solidus' */ *out = c[1]; } len--; c++; /* do not assign, just continue */ continue; } /* next == 'u' */ if (len < 6) { /* Need at least six characters.. */ UNESCAPE_BAIL(UESCAPE_TOOSHORT, 2); } uescval = jsonsl__get_uescape_16((const char *)c + 2); if (uescval == -1) { UNESCAPE_BAIL(PERCENT_BADHEX, -1); } if (last_codepoint) { uint16_t w1 = last_codepoint, w2 = (uint16_t)uescval; uint32_t cp; if (uescval < 0xDC00 || uescval > 0xDFFF) { UNESCAPE_BAIL(INVALID_CODEPOINT, -1); } cp = (w1 & 0x3FF) << 10; cp |= (w2 & 0x3FF); cp += 0x10000; out = jsonsl__writeutf8(cp, out) - 1; last_codepoint = 0; } else if (uescval < 0xD800 || uescval > 0xDFFF) { *oflags |= JSONSL_SPECIALf_NONASCII; out = jsonsl__writeutf8(uescval, out) - 1; } else if (uescval < 0xDC00) { *oflags |= JSONSL_SPECIALf_NONASCII; last_codepoint = (uint16_t)uescval; out--; } else { UNESCAPE_BAIL(INVALID_CODEPOINT, 2); } /* Post uescape cleanup */ len -= 5; /* Gobble up 5 chars after 'u' */ c += 5; continue; /* Only reached by previous branches */ GT_ASSIGN: *out = *c; } if (last_codepoint) { *err = JSONSL_ERROR_INVALID_CODEPOINT; return 0; } *err = JSONSL_ERROR_SUCCESS; return out - begin_p; } /** * Character Table definitions. * These were all generated via srcutil/genchartables.pl */ /** * This table contains the beginnings of non-string * allowable (bareword) values. */ static unsigned short Special_Table[0x100] = { /* 0x00 */ 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, /* 0x1f */ /* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2c */ /* 0x2d */ JSONSL_SPECIALf_DASH /* <-> */, /* 0x2d */ /* 0x2e */ 0,0, /* 0x2f */ /* 0x30 */ JSONSL_SPECIALf_ZERO /* <0> */, /* 0x30 */ /* 0x31 */ JSONSL_SPECIALf_UNSIGNED /* <1> */, /* 0x31 */ /* 0x32 */ JSONSL_SPECIALf_UNSIGNED /* <2> */, /* 0x32 */ /* 0x33 */ JSONSL_SPECIALf_UNSIGNED /* <3> */, /* 0x33 */ /* 0x34 */ JSONSL_SPECIALf_UNSIGNED /* <4> */, /* 0x34 */ /* 0x35 */ JSONSL_SPECIALf_UNSIGNED /* <5> */, /* 0x35 */ /* 0x36 */ JSONSL_SPECIALf_UNSIGNED /* <6> */, /* 0x36 */ /* 0x37 */ JSONSL_SPECIALf_UNSIGNED /* <7> */, /* 0x37 */ /* 0x38 */ JSONSL_SPECIALf_UNSIGNED /* <8> */, /* 0x38 */ /* 0x39 */ JSONSL_SPECIALf_UNSIGNED /* <9> */, /* 0x39 */ /* 0x3a */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x48 */ /* 0x49 */ JSONSL__INF_PROXY /* */, /* 0x49 */ /* 0x4a */ 0,0,0,0, /* 0x4d */ /* 0x4e */ JSONSL__NAN_PROXY /* */, /* 0x4e */ /* 0x4f */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x65 */ /* 0x66 */ JSONSL_SPECIALf_FALSE /* */, /* 0x66 */ /* 0x67 */ 0,0, /* 0x68 */ /* 0x69 */ JSONSL__INF_PROXY /* */, /* 0x69 */ /* 0x6a */ 0,0,0,0, /* 0x6d */ /* 0x6e */ JSONSL_SPECIALf_NULL|JSONSL__NAN_PROXY /* */, /* 0x6e */ /* 0x6f */ 0,0,0,0,0, /* 0x73 */ /* 0x74 */ JSONSL_SPECIALf_TRUE /* */, /* 0x74 */ /* 0x75 */ 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, /* 0x94 */ /* 0x95 */ 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, /* 0xb4 */ /* 0xb5 */ 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, /* 0xd4 */ /* 0xd5 */ 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, /* 0xf4 */ /* 0xf5 */ 0,0,0,0,0,0,0,0,0,0, /* 0xfe */ }; /** * Contains characters which signal the termination of any of the 'special' bareword * values. */ static int Special_Endings[0x100] = { /* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */ /* 0x09 */ 1 /* */, /* 0x09 */ /* 0x0a */ 1 /* */, /* 0x0a */ /* 0x0b */ 0,0, /* 0x0c */ /* 0x0d */ 1 /* */, /* 0x0d */ /* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */ /* 0x20 */ 1 /* */, /* 0x20 */ /* 0x21 */ 0, /* 0x21 */ /* 0x22 */ 1 /* " */, /* 0x22 */ /* 0x23 */ 0,0,0,0,0,0,0,0,0, /* 0x2b */ /* 0x2c */ 1 /* , */, /* 0x2c */ /* 0x2d */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x39 */ /* 0x3a */ 1 /* : */, /* 0x3a */ /* 0x3b */ 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, /* 0x5a */ /* 0x5b */ 1 /* [ */, /* 0x5b */ /* 0x5c */ 1 /* \ */, /* 0x5c */ /* 0x5d */ 1 /* ] */, /* 0x5d */ /* 0x5e */ 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, /* 0x7a */ /* 0x7b */ 1 /* { */, /* 0x7b */ /* 0x7c */ 0, /* 0x7c */ /* 0x7d */ 1 /* } */, /* 0x7d */ /* 0x7e */ 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, /* 0x9d */ /* 0x9e */ 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, /* 0xbd */ /* 0xbe */ 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, /* 0xdd */ /* 0xde */ 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, /* 0xfd */ /* 0xfe */ 0 /* 0xfe */ }; /** * This table contains entries for the allowed whitespace as per RFC 4627 */ static int Allowed_Whitespace[0x100] = { /* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */ /* 0x09 */ 1 /* */, /* 0x09 */ /* 0x0a */ 1 /* */, /* 0x0a */ /* 0x0b */ 0,0, /* 0x0c */ /* 0x0d */ 1 /* */, /* 0x0d */ /* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */ /* 0x20 */ 1 /* */, /* 0x20 */ /* 0x21 */ 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, /* 0x40 */ /* 0x41 */ 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, /* 0x60 */ /* 0x61 */ 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, /* 0x80 */ /* 0x81 */ 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, /* 0xa0 */ /* 0xa1 */ 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, /* 0xc0 */ /* 0xc1 */ 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, /* 0xe0 */ /* 0xe1 */ 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 /* 0xfe */ }; static const int String_No_Passthrough[0x100] = { /* 0x00 */ 1 /* */, /* 0x00 */ /* 0x01 */ 1 /* */, /* 0x01 */ /* 0x02 */ 1 /* */, /* 0x02 */ /* 0x03 */ 1 /* */, /* 0x03 */ /* 0x04 */ 1 /* */, /* 0x04 */ /* 0x05 */ 1 /* */, /* 0x05 */ /* 0x06 */ 1 /* */, /* 0x06 */ /* 0x07 */ 1 /* */, /* 0x07 */ /* 0x08 */ 1 /* */, /* 0x08 */ /* 0x09 */ 1 /* */, /* 0x09 */ /* 0x0a */ 1 /* */, /* 0x0a */ /* 0x0b */ 1 /* */, /* 0x0b */ /* 0x0c */ 1 /* */, /* 0x0c */ /* 0x0d */ 1 /* */, /* 0x0d */ /* 0x0e */ 1 /* */, /* 0x0e */ /* 0x0f */ 1 /* */, /* 0x0f */ /* 0x10 */ 1 /* */, /* 0x10 */ /* 0x11 */ 1 /* */, /* 0x11 */ /* 0x12 */ 1 /* */, /* 0x12 */ /* 0x13 */ 1 /* */, /* 0x13 */ /* 0x14 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x21 */ /* 0x22 */ 1 /* <"> */, /* 0x22 */ /* 0x23 */ 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, /* 0x42 */ /* 0x43 */ 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, /* 0x5b */ /* 0x5c */ 1 /* <\> */, /* 0x5c */ /* 0x5d */ 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, /* 0x7c */ /* 0x7d */ 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, /* 0x9c */ /* 0x9d */ 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, /* 0xbc */ /* 0xbd */ 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, /* 0xdc */ /* 0xdd */ 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, /* 0xfc */ /* 0xfd */ 0,0, /* 0xfe */ }; /** * Allowable two-character 'common' escapes: */ static int Allowed_Escapes[0x100] = { /* 0x00 */ 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, /* 0x1f */ /* 0x20 */ 0,0, /* 0x21 */ /* 0x22 */ 1 /* <"> */, /* 0x22 */ /* 0x23 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2e */ /* 0x2f */ 1 /* */, /* 0x2f */ /* 0x30 */ 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, /* 0x4f */ /* 0x50 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5b */ /* 0x5c */ 1 /* <\> */, /* 0x5c */ /* 0x5d */ 0,0,0,0,0, /* 0x61 */ /* 0x62 */ 1 /* */, /* 0x62 */ /* 0x63 */ 0,0,0, /* 0x65 */ /* 0x66 */ 1 /* */, /* 0x66 */ /* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */ /* 0x6e */ 1 /* */, /* 0x6e */ /* 0x6f */ 0,0,0, /* 0x71 */ /* 0x72 */ 1 /* */, /* 0x72 */ /* 0x73 */ 0, /* 0x73 */ /* 0x74 */ 1 /* */, /* 0x74 */ /* 0x75 */ 1 /* */, /* 0x75 */ /* 0x76 */ 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, /* 0x95 */ /* 0x96 */ 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, /* 0xb5 */ /* 0xb6 */ 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, /* 0xd5 */ /* 0xd6 */ 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, /* 0xf5 */ /* 0xf6 */ 0,0,0,0,0,0,0,0,0, /* 0xfe */ }; /** * This table contains the _values_ for a given (single) escaped character. */ static unsigned char Escape_Equivs[0x100] = { /* 0x00 */ 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, /* 0x1f */ /* 0x20 */ 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, /* 0x3f */ /* 0x40 */ 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, /* 0x5f */ /* 0x60 */ 0,0, /* 0x61 */ /* 0x62 */ 8 /* */, /* 0x62 */ /* 0x63 */ 0,0,0, /* 0x65 */ /* 0x66 */ 12 /* */, /* 0x66 */ /* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */ /* 0x6e */ 10 /* */, /* 0x6e */ /* 0x6f */ 0,0,0, /* 0x71 */ /* 0x72 */ 13 /* */, /* 0x72 */ /* 0x73 */ 0, /* 0x73 */ /* 0x74 */ 9 /* */, /* 0x74 */ /* 0x75 */ 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, /* 0x94 */ /* 0x95 */ 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, /* 0xb4 */ /* 0xb5 */ 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, /* 0xd4 */ /* 0xd5 */ 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, /* 0xf4 */ /* 0xf5 */ 0,0,0,0,0,0,0,0,0,0 /* 0xfe */ }; /* Definitions of above-declared static functions */ static char get_escape_equiv(unsigned c) { return Escape_Equivs[c & 0xff]; } static unsigned extract_special(unsigned c) { return Special_Table[c & 0xff]; } static int is_special_end(unsigned c) { return Special_Endings[c & 0xff]; } static int is_allowed_whitespace(unsigned c) { return c == ' ' || Allowed_Whitespace[c & 0xff]; } static int is_allowed_escape(unsigned c) { return Allowed_Escapes[c & 0xff]; } static int is_simple_char(unsigned c) { return !String_No_Passthrough[c & 0xff]; } /* Clean up all our macros! */ #undef INCR_METRIC #undef INCR_GENERIC #undef INCR_STRINGY_CATCH #undef CASE_DIGITS #undef INVOKE_ERROR #undef STACK_PUSH #undef STACK_POP_NOPOS #undef STACK_POP #undef CALLBACK_AND_POP_NOPOS #undef CALLBACK_AND_POP #undef SPECIAL_POP #undef CUR_CHAR #undef DO_CALLBACK #undef ENSURE_HVAL #undef VERIFY_SPECIAL #undef STATE_SPECIAL_LENGTH #undef IS_NORMAL_NUMBER #undef STATE_NUM_LAST #undef FASTPARSE_EXHAUSTED #undef FASTPARSE_BREAK mongodb-1.3.4/src/libbson/src/jsonsl/jsonsl.h0000664000175000017500000007440713210321137021010 0ustar jmikolajmikola/** * JSON Simple/Stacked/Stateful Lexer. * - Does not buffer data * - Maintains state * - Callback oriented * - Lightweight and fast. One source file and one header file * * Copyright (C) 2012-2015 Mark Nunberg * See included LICENSE file for license details. */ #ifndef JSONSL_H_ #define JSONSL_H_ #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifdef JSONSL_USE_WCHAR typedef jsonsl_char_t wchar_t; typedef jsonsl_uchar_t unsigned wchar_t; #else typedef char jsonsl_char_t; typedef unsigned char jsonsl_uchar_t; #endif /* JSONSL_USE_WCHAR */ #ifdef JSONSL_PARSE_NAN #define JSONSL__NAN_PROXY JSONSL_SPECIALf_NAN #define JSONSL__INF_PROXY JSONSL_SPECIALf_INF #else #define JSONSL__NAN_PROXY 0 #define JSONSL__INF_PROXY 0 #endif /* Stolen from http-parser.h, and possibly others */ #if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #if !defined(_MSC_VER) || _MSC_VER<1400 typedef unsigned int size_t; typedef int ssize_t; #endif #else #include #endif #if (!defined(JSONSL_STATE_GENERIC)) && (!defined(JSONSL_STATE_USER_FIELDS)) #define JSONSL_STATE_GENERIC #endif /* !defined JSONSL_STATE_GENERIC */ #ifdef JSONSL_STATE_GENERIC #define JSONSL_STATE_USER_FIELDS #endif /* JSONSL_STATE_GENERIC */ /* Additional fields for component object */ #ifndef JSONSL_JPR_COMPONENT_USER_FIELDS #define JSONSL_JPR_COMPONENT_USER_FIELDS #endif #ifndef JSONSL_API /** * We require a /DJSONSL_DLL so that users already using this as a static * or embedded library don't get confused */ #if defined(_WIN32) && defined(JSONSL_DLL) #define JSONSL_API __declspec(dllexport) #else #define JSONSL_API #endif /* _WIN32 */ #endif /* !JSONSL_API */ #ifndef JSONSL_INLINE #if defined(_MSC_VER) #define JSONSL_INLINE __inline #elif defined(__GNUC__) #define JSONSL_INLINE __inline__ #else #define JSONSL_INLINE inline #endif /* _MSC_VER or __GNUC__ */ #endif /* JSONSL_INLINE */ #define JSONSL_MAX_LEVELS 512 struct jsonsl_st; typedef struct jsonsl_st *jsonsl_t; typedef struct jsonsl_jpr_st* jsonsl_jpr_t; /** * This flag is true when AND'd against a type whose value * must be in "quoutes" i.e. T_HKEY and T_STRING */ #define JSONSL_Tf_STRINGY 0xffff00 /** * Constant representing the special JSON types. * The values are special and aid in speed (the OBJECT and LIST * values are the char literals of their openings). * * Their actual value is a character which attempts to resemble * some mnemonic reference to the actual type. * * If new types are added, they must fit into the ASCII printable * range (so they should be AND'd with 0x7f and yield something * meaningful) */ #define JSONSL_XTYPE \ X(STRING, '"'|JSONSL_Tf_STRINGY) \ X(HKEY, '#'|JSONSL_Tf_STRINGY) \ X(OBJECT, '{') \ X(LIST, '[') \ X(SPECIAL, '^') \ X(UESCAPE, 'u') typedef enum { #define X(o, c) \ JSONSL_T_##o = c, JSONSL_XTYPE JSONSL_T_UNKNOWN = '?', /* Abstract 'root' object */ JSONSL_T_ROOT = 0 #undef X } jsonsl_type_t; /** * Subtypes for T_SPECIAL. We define them as flags * because more than one type can be applied to a * given object. */ #define JSONSL_XSPECIAL \ X(NONE, 0) \ X(SIGNED, 1<<0) \ X(UNSIGNED, 1<<1) \ X(TRUE, 1<<2) \ X(FALSE, 1<<3) \ X(NULL, 1<<4) \ X(FLOAT, 1<<5) \ X(EXPONENT, 1<<6) \ X(NONASCII, 1<<7) \ X(NAN, 1<<8) \ X(INF, 1<<9) typedef enum { #define X(o,b) \ JSONSL_SPECIALf_##o = b, JSONSL_XSPECIAL #undef X /* Handy flags for checking */ JSONSL_SPECIALf_UNKNOWN = 1 << 10, /** @private Private */ JSONSL_SPECIALf_ZERO = 1 << 11 | JSONSL_SPECIALf_UNSIGNED, /** @private */ JSONSL_SPECIALf_DASH = 1 << 12, /** @private */ JSONSL_SPECIALf_POS_INF = (JSONSL_SPECIALf_INF), JSONSL_SPECIALf_NEG_INF = (JSONSL_SPECIALf_INF|JSONSL_SPECIALf_SIGNED), /** Type is numeric */ JSONSL_SPECIALf_NUMERIC = (JSONSL_SPECIALf_SIGNED| JSONSL_SPECIALf_UNSIGNED), /** Type is a boolean */ JSONSL_SPECIALf_BOOLEAN = (JSONSL_SPECIALf_TRUE|JSONSL_SPECIALf_FALSE), /** Type is an "extended", not integral type (but numeric) */ JSONSL_SPECIALf_NUMNOINT = (JSONSL_SPECIALf_FLOAT|JSONSL_SPECIALf_EXPONENT|JSONSL_SPECIALf_NAN |JSONSL_SPECIALf_INF) } jsonsl_special_t; /** * These are the various types of stack (or other) events * which will trigger a callback. * Like the type constants, this are also mnemonic */ #define JSONSL_XACTION \ X(PUSH, '+') \ X(POP, '-') \ X(UESCAPE, 'U') \ X(ERROR, '!') typedef enum { #define X(a,c) \ JSONSL_ACTION_##a = c, JSONSL_XACTION JSONSL_ACTION_UNKNOWN = '?' #undef X } jsonsl_action_t; /** * Various errors which may be thrown while parsing JSON */ #define JSONSL_XERR \ /* Trailing garbage characters */ \ X(GARBAGE_TRAILING) \ /* We were expecting a 'special' (numeric, true, false, null) */ \ X(SPECIAL_EXPECTED) \ /* The 'special' value was incomplete */ \ X(SPECIAL_INCOMPLETE) \ /* Found a stray token */ \ X(STRAY_TOKEN) \ /* We were expecting a token before this one */ \ X(MISSING_TOKEN) \ /* Cannot insert because the container is not ready */ \ X(CANT_INSERT) \ /* Found a '\' outside a string */ \ X(ESCAPE_OUTSIDE_STRING) \ /* Found a ':' outside of a hash */ \ X(KEY_OUTSIDE_OBJECT) \ /* found a string outside of a container */ \ X(STRING_OUTSIDE_CONTAINER) \ /* Found a null byte in middle of string */ \ X(FOUND_NULL_BYTE) \ /* Current level exceeds limit specified in constructor */ \ X(LEVELS_EXCEEDED) \ /* Got a } as a result of an opening [ or vice versa */ \ X(BRACKET_MISMATCH) \ /* We expected a key, but got something else instead */ \ X(HKEY_EXPECTED) \ /* We got an illegal control character (bad whitespace or something) */ \ X(WEIRD_WHITESPACE) \ /* Found a \u-escape, but there were less than 4 following hex digits */ \ X(UESCAPE_TOOSHORT) \ /* Invalid two-character escape */ \ X(ESCAPE_INVALID) \ /* Trailing comma */ \ X(TRAILING_COMMA) \ /* An invalid number was passed in a numeric field */ \ X(INVALID_NUMBER) \ /* Value is missing for object */ \ X(VALUE_EXPECTED) \ /* The following are for JPR Stuff */ \ \ /* Found a literal '%' but it was only followed by a single valid hex digit */ \ X(PERCENT_BADHEX) \ /* jsonpointer URI is malformed '/' */ \ X(JPR_BADPATH) \ /* Duplicate slash */ \ X(JPR_DUPSLASH) \ /* No leading root */ \ X(JPR_NOROOT) \ /* Allocation failure */ \ X(ENOMEM) \ /* Invalid unicode codepoint detected (in case of escapes) */ \ X(INVALID_CODEPOINT) typedef enum { JSONSL_ERROR_SUCCESS = 0, #define X(e) \ JSONSL_ERROR_##e, JSONSL_XERR #undef X JSONSL_ERROR_GENERIC } jsonsl_error_t; /** * A state is a single level of the stack. * Non-private data (i.e. the 'data' field, see the STATE_GENERIC section) * will remain in tact until the item is popped. * * As a result, it means a parent state object may be accessed from a child * object, (the parents fields will all be valid). This allows a user to create * an ad-hoc hierarchy on top of the JSON one. * */ struct jsonsl_state_st { /** * The JSON object type */ unsigned type; /** If this element is special, then its extended type is here */ unsigned special_flags; /** * The position (in terms of number of bytes since the first call to * jsonsl_feed()) at which the state was first pushed. This includes * opening tokens, if applicable. * * @note For strings (i.e. type & JSONSL_Tf_STRINGY is nonzero) this will * be the position of the first quote. * * @see jsonsl_st::pos which contains the _current_ position and can be * used during a POP callback to get the length of the element. */ size_t pos_begin; /**FIXME: This is redundant as the same information can be derived from * jsonsl_st::pos at pop-time */ size_t pos_cur; /** * Level of recursion into nesting. This is mainly a convenience * variable, as this can technically be deduced from the lexer's * level parameter (though the logic is not that simple) */ unsigned int level; /** * how many elements in the object/list. * For objects (hashes), an element is either * a key or a value. Thus for one complete pair, * nelem will be 2. * * For special types, this will hold the sum of the digits. * This only holds true for values which are simple signed/unsigned * numbers. Otherwise a special flag is set, and extra handling is not * performed. */ uint64_t nelem; /*TODO: merge this and special_flags into a union */ /** * Useful for an opening nest, this will prevent a callback from being * invoked on this item or any of its children */ int ignore_callback; /** * Counter which is incremented each time an escape ('\') is encountered. * This is used internally for non-string types and should only be * inspected by the user if the state actually represents a string * type. */ unsigned int nescapes; /** * Put anything you want here. if JSONSL_STATE_USER_FIELDS is here, then * the macro expansion happens here. * * You can use these fields to store hierarchical or 'tagging' information * for specific objects. * * See the documentation above for the lifetime of the state object (i.e. * if the private data points to allocated memory, it should be freed * when the object is popped, as the state object will be re-used) */ #ifndef JSONSL_STATE_GENERIC JSONSL_STATE_USER_FIELDS #else /** * Otherwise, this is a simple void * pointer for anything you want */ void *data; #endif /* JSONSL_STATE_USER_FIELDS */ }; /**Gets the number of elements in the list. * @param st The state. Must be of type JSONSL_T_LIST * @return number of elements in the list */ #define JSONSL_LIST_SIZE(st) ((st)->nelem) /**Gets the number of key-value pairs in an object * @param st The state. Must be of type JSONSL_T_OBJECT * @return the number of key-value pairs in the object */ #define JSONSL_OBJECT_SIZE(st) ((st)->nelem / 2) /**Gets the numeric value. * @param st The state. Must be of type JSONSL_T_SPECIAL and * special_flags must have the JSONSL_SPECIALf_NUMERIC flag * set. * @return the numeric value of the state. */ #define JSONSL_NUMERIC_VALUE(st) ((st)->nelem) /* * So now we need some special structure for keeping the * JPR info in sync. Preferrably all in a single block * of memory (there's no need for separate allocations. * So we will define a 'table' with the following layout * * Level nPosbl JPR1_last JPR2_last JPR3_last * * 0 1 NOMATCH POSSIBLE POSSIBLE * 1 0 NOMATCH NOMATCH COMPLETE * [ table ends here because no further path is possible] * * Where the JPR..n corresponds to the number of JPRs * requested, and nPosble is a quick flag to determine * * the number of possibilities. In the future this might * be made into a proper 'jump' table, * * Since we always mark JPRs from the higher levels descending * into the lower ones, a prospective child match would first * look at the parent table to check the possibilities, and then * see which ones were possible.. * * Thus, the size of this blob would be (and these are all ints here) * nLevels * nJPR * 2. * * the 'Width' of the table would be nJPR*2, and the 'height' would be * nlevels */ /** * This is called when a stack change ocurs. * * @param jsn The lexer * @param action The type of action, this can be PUSH or POP * @param state A pointer to the stack currently affected by the action * @param at A pointer to the position of the input buffer which triggered * this action. */ typedef void (*jsonsl_stack_callback)( jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st* state, const jsonsl_char_t *at); /** * This is called when an error is encountered. * Sometimes it's possible to 'erase' characters (by replacing them * with whitespace). If you think you have corrected the error, you * can return a true value, in which case the parser will backtrack * and try again. * * @param jsn The lexer * @param error The error which was thrown * @param state the current state * @param a pointer to the position of the input buffer which triggered * the error. Note that this is not const, this is because you have the * possibility of modifying the character in an attempt to correct the * error * * @return zero to bail, nonzero to try again (this only makes sense if * the input buffer has been modified by this callback) */ typedef int (*jsonsl_error_callback)( jsonsl_t jsn, jsonsl_error_t error, struct jsonsl_state_st* state, jsonsl_char_t *at); struct jsonsl_st { /** Public, read-only */ /** This is the current level of the stack */ unsigned int level; /** Flag set to indicate we should stop processing */ unsigned int stopfl; /** * This is the current position, relative to the beginning * of the stream. */ size_t pos; /** This is the 'bytes' variable passed to feed() */ const jsonsl_char_t *base; /** Callback invoked for PUSH actions */ jsonsl_stack_callback action_callback_PUSH; /** Callback invoked for POP actions */ jsonsl_stack_callback action_callback_POP; /** Default callback for any action, if neither PUSH or POP callbacks are defined */ jsonsl_stack_callback action_callback; /** * Do not invoke callbacks for objects deeper than this level. * NOTE: This field establishes the lower bound for ignored callbacks, * and is thus misnamed. `min_ignore_level` would actually make more * sense, but we don't want to break API. */ unsigned int max_callback_level; /** The error callback. Invoked when an error happens. Should not be NULL */ jsonsl_error_callback error_callback; /* these are boolean flags you can modify. You will be called * about notification for each of these types if the corresponding * variable is true. */ /** * @name Callback Booleans. * These determine whether a callback is to be invoked for certain types of objects * @{*/ /** Boolean flag to enable or disable the invokcation for events on this type*/ int call_SPECIAL; int call_OBJECT; int call_LIST; int call_STRING; int call_HKEY; /*@}*/ /** * @name u-Escape handling * Special handling for the \\u-f00d type sequences. These are meant * to be translated back into the corresponding octet(s). * A special callback (if set) is invoked with *at=='u'. An application * may wish to temporarily suspend parsing and handle the 'u-' sequence * internally (or not). */ /*@{*/ /** Callback to be invoked for a u-escape */ jsonsl_stack_callback action_callback_UESCAPE; /** Boolean flag, whether to invoke the callback */ int call_UESCAPE; /** Boolean flag, whether we should return after encountering a u-escape: * the callback is invoked and then we return if this is true */ int return_UESCAPE; /*@}*/ struct { int allow_trailing_comma; } options; /** Put anything here */ void *data; /*@{*/ /** Private */ int in_escape; char expecting; char tok_last; int can_insert; unsigned int levels_max; #ifndef JSONSL_NO_JPR size_t jpr_count; jsonsl_jpr_t *jprs; /* Root pointer for JPR matching information */ size_t *jpr_root; #endif /* JSONSL_NO_JPR */ /*@}*/ /** * This is the stack. Its upper bound is levels_max, or the * nlevels argument passed to jsonsl_new. If you modify this structure, * make sure that this member is last. */ struct jsonsl_state_st stack[1]; }; /** * Creates a new lexer object, with capacity for recursion up to nlevels * * @param nlevels maximum recursion depth */ JSONSL_API jsonsl_t jsonsl_new(int nlevels); /** * Feeds data into the lexer. * * @param jsn the lexer object * @param bytes new data to be fed * @param nbytes size of new data */ JSONSL_API void jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes); /** * Resets the internal parser state. This does not free the parser * but does clean it internally, so that the next time feed() is called, * it will be treated as a new stream * * @param jsn the lexer */ JSONSL_API void jsonsl_reset(jsonsl_t jsn); /** * Frees the lexer, cleaning any allocated memory taken * * @param jsn the lexer */ JSONSL_API void jsonsl_destroy(jsonsl_t jsn); /** * Gets the 'parent' element, given the current one * * @param jsn the lexer * @param cur the current nest, which should be a struct jsonsl_nest_st */ static JSONSL_INLINE struct jsonsl_state_st *jsonsl_last_state(const jsonsl_t jsn, const struct jsonsl_state_st *state) { /* Don't complain about overriding array bounds */ if (state->level > 1) { return jsn->stack + state->level - 1; } else { return NULL; } } /** * Gets the state of the last fully consumed child of this parent. This is * only valid in the parent's POP callback. * * @param the lexer * @return A pointer to the child. */ static JSONSL_INLINE struct jsonsl_state_st *jsonsl_last_child(const jsonsl_t jsn, const struct jsonsl_state_st *parent) { return jsn->stack + (parent->level + 1); } /**Call to instruct the parser to stop parsing and return. This is valid * only from within a callback */ static JSONSL_INLINE void jsonsl_stop(jsonsl_t jsn) { jsn->stopfl = 1; } /** * This enables receiving callbacks on all events. Doesn't do * anything special but helps avoid some boilerplate. * This does not touch the UESCAPE callbacks or flags. */ static JSONSL_INLINE void jsonsl_enable_all_callbacks(jsonsl_t jsn) { jsn->call_HKEY = 1; jsn->call_STRING = 1; jsn->call_OBJECT = 1; jsn->call_SPECIAL = 1; jsn->call_LIST = 1; } /** * A macro which returns true if the current state object can * have children. This means a list type or an object type. */ #define JSONSL_STATE_IS_CONTAINER(state) \ (state->type == JSONSL_T_OBJECT || state->type == JSONSL_T_LIST) /** * These two functions, dump a string representation * of the error or type, respectively. They will never * return NULL */ JSONSL_API const char* jsonsl_strerror(jsonsl_error_t err); JSONSL_API const char* jsonsl_strtype(jsonsl_type_t jt); /** * Dumps global metrics to the screen. This is a noop unless * jsonsl was compiled with JSONSL_USE_METRICS */ JSONSL_API void jsonsl_dump_global_metrics(void); /* This macro just here for editors to do code folding */ #ifndef JSONSL_NO_JPR /** * @name JSON Pointer API * * JSONPointer API. This isn't really related to the lexer (at least not yet) * JSONPointer provides an extremely simple specification for providing * locations within JSON objects. We will extend it a bit and allow for * providing 'wildcard' characters by which to be able to 'query' the stream. * * See http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer-00 * * Currently I'm implementing the 'single query' API which can only use a single * query component. In the future I will integrate my yet-to-be-published * Boyer-Moore-esque prefix searching implementation, in order to allow * multiple paths to be merged into one for quick and efficient searching. * * * JPR (as we'll refer to it within the source) can be used by splitting * the components into mutliple sections, and incrementally 'track' each * component. When JSONSL delivers a 'pop' callback for a string, or a 'push' * callback for an object, we will check to see whether the index matching * the component corresponding to the current level contains a match * for our path. * * In order to do this properly, a structure must be maintained within the * parent indicating whether its children are possible matches. This flag * will be 'inherited' by call children which may conform to the match * specification, and discarded by all which do not (thereby eliminating * their children from inheriting it). * * A successful match is a complete one. One can provide multiple paths with * multiple levels of matches e.g. * /foo/bar/baz/^/blah * * @{ */ /** The wildcard character */ #ifndef JSONSL_PATH_WILDCARD_CHAR #define JSONSL_PATH_WILDCARD_CHAR '^' #endif /* WILDCARD_CHAR */ #define JSONSL_XMATCH \ X(COMPLETE,1) \ X(POSSIBLE,0) \ X(NOMATCH,-1) \ X(TYPE_MISMATCH, -2) typedef enum { #define X(T,v) \ JSONSL_MATCH_##T = v, JSONSL_XMATCH #undef X JSONSL_MATCH_UNKNOWN } jsonsl_jpr_match_t; typedef enum { JSONSL_PATH_STRING = 1, JSONSL_PATH_WILDCARD, JSONSL_PATH_NUMERIC, JSONSL_PATH_ROOT, /* Special */ JSONSL_PATH_INVALID = -1, JSONSL_PATH_NONE = 0 } jsonsl_jpr_type_t; struct jsonsl_jpr_component_st { /** The string the component points to */ char *pstr; /** if this is a numeric type, the number is 'cached' here */ unsigned long idx; /** The length of the string */ size_t len; /** The type of component (NUMERIC or STRING) */ jsonsl_jpr_type_t ptype; /** Set this to true to enforce type checking between dict keys and array * indices. jsonsl_jpr_match() will return TYPE_MISMATCH if it detects * that an array index is actually a child of a dictionary. */ short is_arridx; /* Extra fields (for more advanced searches. Default is empty) */ JSONSL_JPR_COMPONENT_USER_FIELDS }; struct jsonsl_jpr_st { /** Path components */ struct jsonsl_jpr_component_st *components; size_t ncomponents; /**Type of the match to be expected. If nonzero, will be compared against * the actual type */ unsigned match_type; /** Base of allocated string for components */ char *basestr; /** The original match string. Useful for returning to the user */ char *orig; size_t norig; }; /** * Create a new JPR object. * * @param path the JSONPointer path specification. * @param errp a pointer to a jsonsl_error_t. If this function returns NULL, * then more details will be in this variable. * * @return a new jsonsl_jpr_t object, or NULL on error. */ JSONSL_API jsonsl_jpr_t jsonsl_jpr_new(const char *path, jsonsl_error_t *errp); /** * Destroy a JPR object */ JSONSL_API void jsonsl_jpr_destroy(jsonsl_jpr_t jpr); /** * Match a JSON object against a type and specific level * * @param jpr the JPR object * @param parent_type the type of the parent (should be T_LIST or T_OBJECT) * @param parent_level the level of the parent * @param key the 'key' of the child. If the parent is an array, this should be * empty. * @param nkey - the length of the key. If the parent is an array (T_LIST), then * this should be the current index. * * NOTE: The key of the child means any kind of associative data related to the * element. Thus: <<< { "foo" : [ >>, * the opening array's key is "foo". * * @return a status constant. This indicates whether a match was excluded, possible, * or successful. */ JSONSL_API jsonsl_jpr_match_t jsonsl_jpr_match(jsonsl_jpr_t jpr, unsigned int parent_type, unsigned int parent_level, const char *key, size_t nkey); /** * Alternate matching algorithm. This matching algorithm does not use * JSONPointer but relies on a more structured searching mechanism. It * assumes that there is a clear distinction between array indices and * object keys. In this case, the jsonsl_path_component_st::ptype should * be set to @ref JSONSL_PATH_NUMERIC for an array index (the * jsonsl_path_comonent_st::is_arridx field will be removed in a future * version). * * @param jpr The path * @param parent The parent structure. Can be NULL if this is the root object * @param child The child structure. Should not be NULL * @param key Object key, if an object * @param nkey Length of object key * @return Status constant if successful * * @note * For successful matching, both the key and the path itself should be normalized * to contain 'proper' utf8 sequences rather than utf16 '\uXXXX' escapes. This * should currently be done in the application. Another version of this function * may use a temporary buffer in such circumstances (allocated by the application). * * Since this function also checks the state of the child, it should only * be called on PUSH callbacks, and not POP callbacks */ JSONSL_API jsonsl_jpr_match_t jsonsl_path_match(jsonsl_jpr_t jpr, const struct jsonsl_state_st *parent, const struct jsonsl_state_st *child, const char *key, size_t nkey); /** * Associate a set of JPR objects with a lexer instance. * This should be called before the lexer has been fed any data (and * behavior is undefined if you don't adhere to this). * * After using this function, you may subsequently call match_state() on * given states (presumably from within the callbacks). * * Note that currently the first JPR is the quickest and comes * pre-allocated with the state structure. Further JPR objects * are chained. * * @param jsn The lexer * @param jprs An array of jsonsl_jpr_t objects * @param njprs How many elements in the jprs array. */ JSONSL_API void jsonsl_jpr_match_state_init(jsonsl_t jsn, jsonsl_jpr_t *jprs, size_t njprs); /** * This follows the same semantics as the normal match, * except we infer parent and type information from the relevant state objects. * The match status (for all possible JPR objects) is set in the *out parameter. * * If a match has succeeded, then its JPR object will be returned. In all other * instances, NULL is returned; * * @param jpr The jsonsl_jpr_t handle * @param state The jsonsl_state_st which is a candidate * @param key The hash key (if applicable, can be NULL if parent is list) * @param nkey Length of hash key (if applicable, can be zero if parent is list) * @param out A pointer to a jsonsl_jpr_match_t. This will be populated with * the match result * * @return If a match was completed in full, then the JPR object containing * the matching path will be returned. Otherwise, the return is NULL (note, this * does not mean matching has failed, it can still be part of the match: check * the out parameter). */ JSONSL_API jsonsl_jpr_t jsonsl_jpr_match_state(jsonsl_t jsn, struct jsonsl_state_st *state, const char *key, size_t nkey, jsonsl_jpr_match_t *out); /** * Cleanup any memory allocated and any states set by * match_state_init() and match_state() * @param jsn The lexer */ JSONSL_API void jsonsl_jpr_match_state_cleanup(jsonsl_t jsn); /** * Return a string representation of the match result returned by match() */ JSONSL_API const char *jsonsl_strmatchtype(jsonsl_jpr_match_t match); /* @}*/ /** * Utility function to convert escape sequences into their original form. * * The decoders I've sampled do not seem to specify a standard behavior of what * to escape/unescape. * * RFC 4627 Mandates only that the quoute, backslash, and ASCII control * characters (0x00-0x1f) be escaped. It is often common for applications * to escape a '/' - however this may also be desired behavior. the JSON * spec is not clear on this, and therefore jsonsl leaves it up to you. * * Additionally, sometimes you may wish to _normalize_ JSON. This is specifically * true when dealing with 'u-escapes' which can be expressed perfectly fine * as utf8. One use case for normalization is JPR string comparison, in which * case two effectively equivalent strings may not match because one is using * u-escapes and the other proper utf8. To normalize u-escapes only, pass in * an empty `toEscape` table, enabling only the `u` index. * * @param in The input string. * @param out An allocated output (should be the same size as in) * @param len the size of the buffer * @param toEscape - A sparse array of characters to unescape. Characters * which are not present in this array, e.g. toEscape['c'] == 0 will be * ignored and passed to the output in their original form. * @param oflags If not null, and a \uXXXX escape expands to a non-ascii byte, * then this variable will have the SPECIALf_NONASCII flag on. * * @param err A pointer to an error variable. If an error ocurrs, it will be * set in this variable * @param errat If not null and an error occurs, this will be set to point * to the position within the string at which the offending character was * encountered. * * @return The effective size of the output buffer. * * @note * This function now encodes the UTF8 equivalents of utf16 escapes (i.e. * 'u-escapes'). Previously this would encode the escapes as utf16 literals, * which while still correct in some sense was confusing for many (especially * considering that the inputs were variations of char). * * @note * The output buffer will never be larger than the input buffer, since * standard escape sequences (i.e. '\t') occupy two bytes in the source * but only one byte (when unescaped) in the output. Likewise u-escapes * (i.e. \uXXXX) will occupy six bytes in the source, but at the most * two bytes when escaped. */ JSONSL_API size_t jsonsl_util_unescape_ex(const char *in, char *out, size_t len, const int toEscape[128], unsigned *oflags, jsonsl_error_t *err, const char **errat); /** * Convenience macro to avoid passing too many parameters */ #define jsonsl_util_unescape(in, out, len, toEscape, err) \ jsonsl_util_unescape_ex(in, out, len, toEscape, NULL, err, NULL) #endif /* JSONSL_NO_JPR */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JSONSL_H_ */ mongodb-1.3.4/src/libbson/VERSION_CURRENT0000664000175000017500000000000513210321137017461 0ustar jmikolajmikola1.8.2mongodb-1.3.4/src/libbson/VERSION_RELEASED0000664000175000017500000000000513210321137017523 0ustar jmikolajmikola1.8.2mongodb-1.3.4/src/libmongoc/build/autotools/m4/ac_check_typedef.m40000664000175000017500000000264013210321137024711 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.3.4/src/libmongoc/build/autotools/m4/ac_compile_check_sizeof.m40000664000175000017500000000156613210321137026266 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.3.4/src/libmongoc/build/autotools/m4/ac_create_stdint_h.m40000664000175000017500000003662213210321137025262 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.3.4/src/libmongoc/build/autotools/m4/ax_check_compile_flag.m40000664000175000017500000000625113210321137025721 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.3.4/src/libmongoc/build/autotools/m4/ax_check_link_flag.m40000664000175000017500000000576013210321137025232 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.3.4/src/libmongoc/build/autotools/m4/ax_prototype.m40000664000175000017500000001726713210321137024221 0ustar jmikolajmikola# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_prototype.html # =========================================================================== # # SYNOPSIS # # AX_PROTOTYPE(function, includes, code, TAG1, values1 [, TAG2, values2 [...]]) # # DESCRIPTION # # Try all the combinations of , ... to successfully compile # . , , ... are substituted in and with # values found in , , ... respectively. , # , ... contain a list of possible values for each corresponding # tag and all combinations are tested. When AC_TRY_COMPILE(include, code) # is successfull for a given substitution, the macro stops and defines the # following macros: FUNCTION_TAG1, FUNCTION_TAG2, ... using AC_DEFINE() # with values set to the current values of , , ... If no # combination is successfull the configure script is aborted with a # message. # # Intended purpose is to find which combination of argument types is # acceptable for a given function . It is recommended to list # the most specific types first. For instance ARG1, [size_t, int] instead # of ARG1, [int, size_t]. # # Generic usage pattern: # # 1) add a call in configure.in # # AX_PROTOTYPE(...) # # 2) call autoheader to see which symbols are not covered # # 3) add the lines in acconfig.h # # /* Type of Nth argument of function */ # #undef FUNCTION_ARGN # # 4) Within the code use FUNCTION_ARGN instead of an hardwired type # # Complete example: # # 1) configure.in # # AX_PROTOTYPE(getpeername, # [ # #include # #include # ], # [ # int a = 0; # ARG2 * b = 0; # ARG3 * c = 0; # getpeername(a, b, c); # ], # ARG2, [struct sockaddr, void], # ARG3, [socklen_t, size_t, int, unsigned int, long unsigned int]) # # 2) call autoheader # # autoheader: Symbol `GETPEERNAME_ARG2' is not covered by ./acconfig.h # autoheader: Symbol `GETPEERNAME_ARG3' is not covered by ./acconfig.h # # 3) acconfig.h # # /* Type of second argument of getpeername */ # #undef GETPEERNAME_ARG2 # # /* Type of third argument of getpeername */ # #undef GETPEERNAME_ARG3 # # 4) in the code # # ... # GETPEERNAME_ARG2 name; # GETPEERNAME_ARG3 namelen; # ... # ret = getpeername(socket, &name, &namelen); # ... # # Implementation notes: generating all possible permutations of the # arguments is not easily done with the usual mixture of shell and m4, # that is why this macro is almost 100% m4 code. It generates long but # simple to read code. # # LICENSE # # Copyright (c) 2009 Loic Dachary # # 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, 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 6 AU_ALIAS([AC_PROTOTYPE], [AX_PROTOTYPE]) AC_DEFUN([AX_PROTOTYPE],[ dnl dnl Upper case function name dnl pushdef([function],translit([$1], [a-z], [A-Z])) dnl dnl Collect tags that will be substituted dnl pushdef([tags],[AX_PROTOTYPE_TAGS(builtin([shift],builtin([shift],builtin([shift],$@))))]) dnl dnl Wrap in a 1 time loop, when a combination is found break to stop the combinatory exploration dnl for i in 1 do AX_PROTOTYPE_LOOP(AX_PROTOTYPE_REVERSE($1, AX_PROTOTYPE_SUBST($2,tags),AX_PROTOTYPE_SUBST($3,tags),builtin([shift],builtin([shift],builtin([shift],$@))))) AC_MSG_ERROR($1 unable to find a working combination) done popdef([tags]) popdef([function]) ]) dnl dnl AX_PROTOTYPE_REVERSE(list) dnl dnl Reverse the order of the dnl AC_DEFUN([AX_PROTOTYPE_REVERSE],[ifelse($#,0,,$#,1,[[$1]],[AX_PROTOTYPE_REVERSE(builtin([shift],$@)),[$1]])]) dnl dnl AX_PROTOTYPE_SUBST(string, tag) dnl dnl Substitute all occurence of in with _VAL. dnl Assumes that tag_VAL is a macro containing the value associated to tag. dnl AC_DEFUN([AX_PROTOTYPE_SUBST],[ifelse($2,,[$1],[AX_PROTOTYPE_SUBST(patsubst([$1],[$2],[$2[]_VAL]),builtin([shift],builtin([shift],$@)))])]) dnl dnl AX_PROTOTYPE_TAGS([tag, values, [tag, values ...]]) dnl dnl Generate a list of by skipping . dnl AC_DEFUN([AX_PROTOTYPE_TAGS],[ifelse($1,,[],[$1, AX_PROTOTYPE_TAGS(builtin([shift],builtin([shift],$@)))])]) dnl dnl AX_PROTOTYPE_DEFINES(tags) dnl dnl Generate a AC_DEFINE(function_tag, tag_VAL) for each tag in list dnl Assumes that function is a macro containing the name of the function in upper case dnl and that tag_VAL is a macro containing the value associated to tag. dnl AC_DEFUN([AX_PROTOTYPE_DEFINES],[ifelse($1,,[], [AC_DEFINE(function[]_$1, $1_VAL, [ ]) AC_SUBST(function[]_$1, "$1_VAL") AX_PROTOTYPE_DEFINES(builtin([shift],$@))])]) dnl dnl AX_PROTOTYPE_STATUS(tags) dnl dnl Generates a message suitable for argument to AC_MSG_* macros. For each tag dnl in the list the message tag => tag_VAL is generated. dnl Assumes that tag_VAL is a macro containing the value associated to tag. dnl AC_DEFUN([AX_PROTOTYPE_STATUS],[ifelse($1,,[],[$1 => $1_VAL AX_PROTOTYPE_STATUS(builtin([shift],$@))])]) dnl dnl AX_PROTOTYPE_EACH(tag, values) dnl dnl Call AX_PROTOTYPE_LOOP for each values and define the macro tag_VAL to dnl the current value. dnl AC_DEFUN([AX_PROTOTYPE_EACH],[ ifelse($2,, [ ], [ pushdef([$1_VAL], $2) AX_PROTOTYPE_LOOP(rest) popdef([$1_VAL]) AX_PROTOTYPE_EACH($1, builtin([shift], builtin([shift], $@))) ]) ]) dnl dnl AX_PROTOTYPE_LOOP([tag, values, [tag, values ...]], code, include, function) dnl dnl If there is a tag/values pair, call AX_PROTOTYPE_EACH with it. dnl If there is no tag/values pair left, tries to compile the code and include dnl using AC_TRY_COMPILE. If it compiles, AC_DEFINE all the tags to their dnl current value and exit with success. dnl AC_DEFUN([AX_PROTOTYPE_LOOP],[ ifelse(builtin([eval], $# > 3), 1, [ pushdef([rest],[builtin([shift],builtin([shift],$@))]) AX_PROTOTYPE_EACH($2,$1) popdef([rest]) ], [ AC_MSG_CHECKING($3 AX_PROTOTYPE_STATUS(tags)) dnl dnl Activate fatal warnings if possible, gives better guess dnl ac_save_CPPFLAGS="$CPPFLAGS" if test "$GCC" = "yes" ; then CPPFLAGS="$CPPFLAGS -Werror" ; fi AC_TRY_COMPILE($2, $1, [ CPPFLAGS="$ac_save_CPPFLAGS" AC_MSG_RESULT(ok) AX_PROTOTYPE_DEFINES(tags) break; ], [ CPPFLAGS="$ac_save_CPPFLAGS" AC_MSG_RESULT(not ok) ]) ] ) ]) mongodb-1.3.4/src/libmongoc/build/autotools/m4/ax_pthread.m40000664000175000017500000003267613210321137023604 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.3.4/src/libmongoc/build/autotools/m4/pkg.m40000664000175000017500000001623113210321137022233 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.3.4/src/libmongoc/build/autotools/m4/silent.m40000664000175000017500000000267213210321137022754 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.3.4/src/libmongoc/build/autotools/AutomaticInitAndCleanup.m40000664000175000017500000000023613210321137025635 0ustar jmikolajmikolaAS_IF([test "$enable_automatic_init_and_cleanup" != "no"], [ AC_SUBST(MONGOC_NO_AUTOMATIC_GLOBALS, 0) ], [ AC_SUBST(MONGOC_NO_AUTOMATIC_GLOBALS, 1) ]) mongodb-1.3.4/src/libmongoc/build/autotools/CheckCompiler.m40000664000175000017500000000432313210321137023641 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"], []) # The type of parameters for accept, getpeername, getsockname, getsockopt # all vary the same way by platform. AX_PROTOTYPE(accept, [ #include #include ], [ int a = 0; ARG2 *b = 0; ARG3 *c = 0; accept (a, b, c);], ARG2, [struct sockaddr, void], ARG3, [socklen_t, size_t, int]) MONGOC_SOCKET_ARG2="$ACCEPT_ARG2" AC_SUBST(MONGOC_SOCKET_ARG2) MONGOC_SOCKET_ARG3="$ACCEPT_ARG3" AC_SUBST(MONGOC_SOCKET_ARG3) 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.3.4/src/libmongoc/build/autotools/CheckHost.m40000664000175000017500000000155413210321137023007 0ustar jmikolajmikolaAC_CANONICAL_HOST os_win32=no os_netbsd=no os_freebsd=no os_openbsd=no os_hpux=no os_linux=no os_solaris=no os_darwin=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 ;; *-*-hpux*) os_hpux=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.3.4/src/libmongoc/build/autotools/CheckProgs.m40000664000175000017500000000077713210321137023172 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 AC_CHECK_HEADERS_ONCE([strings.h]) AC_CHECK_HEADERS_ONCE([unistd.h]) AC_CHECK_HEADERS_ONCE([stdarg.h]) # Optional for documentation AC_PATH_PROG(SPHINX_BUILD, sphinx-build) AC_PROG_INSTALL mongodb-1.3.4/src/libmongoc/build/autotools/CheckSSL.m40000664000175000017500000001337613210321137022540 0ustar jmikolajmikolaAC_MSG_CHECKING([whether to enable crypto and TLS]) AC_ARG_ENABLE([ssl], [AS_HELP_STRING([--enable-ssl=@<:@auto/no/openssl/libressl/darwin@:>@], [Enable TLS connections and SCRAM-SHA-1 authentication.])], [], [enable_ssl=auto]) AC_MSG_RESULT([$enable_ssl]) AC_MSG_CHECKING([whether to use system crypto profile]) AC_ARG_ENABLE(crypto-system-profile, AC_HELP_STRING([--enable-crypto-system-profile], [use system crypto profile (OpenSSL only) [default=no]]), [], [enable_crypto_system_profile="no"]) AC_MSG_RESULT([$enable_crypto_system_profile]) AS_IF([test "$enable_ssl" != "no"],[ AS_IF([test "$enable_ssl" != "darwin" -a "$enable_ssl" != "libressl"],[ PKG_CHECK_MODULES(SSL, [openssl], [enable_openssl=auto], [ AC_CHECK_LIB([ssl],[SSL_library_init],[have_ssl_lib=yes],[have_ssl_lib=no]) AC_CHECK_LIB([crypto],[EVP_DigestInit_ex],[have_crypto_lib=yes],[have_crypto_lib=no]) if test "$have_ssl_lib" = "no" -o "$have_crypto_lib" = "no" ; then if test "$enable_ssl" = "openssl"; then AC_MSG_ERROR([You must install the OpenSSL libraries and development headers to enable OpenSSL support.]) else AC_MSG_WARN([You must install the OpenSSL libraries and development headers to enable OpenSSL support.]) fi fi if test "$have_ssl_lib" = "yes" -a "$have_crypto_lib" = "yes"; then SSL_LIBS="-lssl -lcrypto" enable_ssl=openssl fi ]) ]) AS_IF([test "$enable_ssl" = "libressl"],[ PKG_CHECK_MODULES(SSL, [libtls], [enable_ssl=libressl], [ AC_CHECK_LIB([tls],[tls_init],[ SSL_LIBS="-ltls -lcrypto" enable_ssl=libressl ]) ]) ]) dnl PKG_CHECK_MODULES() doesn't check for headers dnl OSX for example has the lib, but not headers, so double confirm if OpenSSL works AS_IF([test "$enable_ssl" = "openssl" -o "$enable_openssl" = "auto"], [ old_CFLAGS=$CFLAGS CFLAGS=$SSL_CFLAGS 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" = "yes"; then enable_ssl=openssl elif test "$enable_ssl" = "openssl"; then AC_MSG_ERROR([You must install the OpenSSL development headers to enable OpenSSL support.]) else SSL_LIBS="" enable_ssl=auto fi AC_CHECK_DECLS([ASN1_STRING_get0_data], [have_ASN1_STRING_get0_data=yes], [have_ASN1_STRING_get0_data=no], [[#include ]]) CFLAGS=$old_CFLAGS ]) AS_IF([test "$enable_ssl" != "openssl" -a "$os_darwin" = "yes"],[ SSL_LIBS="-framework Security -framework CoreFoundation" enable_ssl="darwin" ]) dnl If its still auto, its no. AS_IF([test "$enable_ssl" = "auto"],[ enable_ssl="no" ]) AC_MSG_CHECKING([which TLS library to use]) AC_MSG_RESULT([$enable_ssl]) ], [enable_ssl=no]) AC_SUBST(SSL_CFLAGS) AC_SUBST(SSL_LIBS) dnl Disable Windows SSL+Crypto AC_SUBST(MONGOC_ENABLE_SSL_SECURE_CHANNEL, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_CNG, 0) if test "$enable_ssl" = "darwin" -o "$enable_ssl" = "openssl" -o "$enable_ssl" = "libressl"; then AC_SUBST(MONGOC_ENABLE_SSL, 1) AC_SUBST(MONGOC_ENABLE_CRYPTO, 1) if test "$enable_ssl" = "darwin"; then AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 0) AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 0) AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 1) AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 1) elif test "$enable_ssl" = "openssl"; then AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 1) AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 0) AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 1) AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 0) elif test "$enable_ssl" = "libressl"; then AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 1) AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 0) AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 1) AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 0) fi else AC_SUBST(MONGOC_ENABLE_SSL, 0) AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 0) AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 0) AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 0) fi if test "$have_ASN1_STRING_get0_data" = "yes"; then AC_SUBST(MONGOC_HAVE_ASN1_STRING_GET0_DATA, 1) else AC_SUBST(MONGOC_HAVE_ASN1_STRING_GET0_DATA, 0) fi if test "x$enable_crypto_system_profile" = xyes; then if test "$enable_ssl" = "openssl"; then AC_SUBST(MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE, 1) else AC_MSG_ERROR([--enable-crypto-system-profile only available with OpenSSL.]) fi else AC_SUBST(MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE, 0) fi AM_CONDITIONAL([ENABLE_SSL], [test "$enable_ssl" = "darwin" -o "$enable_ssl" = "openssl" -o "$enable_ssl" = "libressl"]) AM_CONDITIONAL([ENABLE_SSL_LIBRESSL], [test "$enable_ssl" = "libressl"]) AM_CONDITIONAL([ENABLE_SSL_OPENSSL], [test "$enable_ssl" = "openssl"]) AM_CONDITIONAL([ENABLE_SSL_SECURE_TRANSPORT], [test "$enable_ssl" = "darwin"]) AM_CONDITIONAL([ENABLE_SSL_SECURE_CHANNEL], false) AM_CONDITIONAL([ENABLE_CRYPTO], [test "$enable_ssl" = "darwin" -o "$enable_ssl" = "openssl" -o "$enable_ssl" = "libressl"]) AM_CONDITIONAL([ENABLE_CRYPTO_LIBCRYPTO], [test "$enable_ssl" = "openssl" -o "$enable_ssl" = "libressl"]) AM_CONDITIONAL([ENABLE_CRYPTO_CNG], false) AM_CONDITIONAL([ENABLE_CRYPTO_COMMON_CRYPTO], [test "$enable_ssl" = "darwin"]) mongodb-1.3.4/src/libmongoc/build/autotools/CheckSasl.m40000664000175000017500000001006213210321137022766 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"],[ AS_IF( [test "$enable_sasl" = "gssapi"], [ sasl_mode=gssapi AS_IF( [test "$os_darwin" = "yes"], [SASL_LIBS="-framework GSS"], [ AC_CHECK_HEADERS( [gssapi/gssapi.h], [have_gssapi_headers=yes], [have_gssapi_headers=no] ) PKG_CHECK_MODULES(KRB5_GSSAPI, [krb5-gssapi], [have_krb5_gssapi=yes], [have_krb5_gssapi=no] ) if test "$have_gssapi_headers" = "no" -o "$have_krb5_gssapi" = "no"; then AC_MSG_ERROR([You must install the krb5 libraries and development headers to enable GSSAPI support.]) fi SASL_CFLAGS=$KRB5_GSSAPI_CFLAGS SASL_LIBS=$KRB5_GSSAPI_LIBS ] ) ], [ 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 old_CFLAGS=$CFLAGS CFLAGS=$SASL_CFLAGS 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 CFLAGS=$old_CFLAGS 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 ]) ] ) ] ) ]) if test "$enable_sasl" = "auto" -a "$sasl_mode" != "no"; then AC_CHECK_HEADERS([sasl/sasl.h], [have_sasl_headers=yes], [have_sasl_headers=no]) if test "$have_sasl_headers" = "no"; then SASL_LIBS="" enable_sasl=no sasl_mode=no fi fi AM_CONDITIONAL([ENABLE_SASL], [test "$sasl_mode" != "no"]) AM_CONDITIONAL([ENABLE_SASL_GSSAPI], [test "$sasl_mode" = "gssapi"]) AM_CONDITIONAL([ENABLE_SASL_CYRUS], [test "$sasl_mode" = "sasl" -o "$sasl_mode" = "sasl2"]) AM_CONDITIONAL([ENABLE_SASL_SSPI], false) 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_SUBST(MONGOC_ENABLE_SASL_SSPI, 0) if test "$sasl_mode" = "gssapi" ; then AC_SUBST(MONGOC_ENABLE_SASL_GSSAPI, 1) AC_SUBST(MONGOC_ENABLE_SASL_CYRUS, 0) AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) else AC_SUBST(MONGOC_ENABLE_SASL_GSSAPI, 0) AC_SUBST(MONGOC_ENABLE_SASL_CYRUS, 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 fi else AC_SUBST(MONGOC_ENABLE_SASL, 0) AC_SUBST(MONGOC_ENABLE_SASL_CYRUS, 0) AC_SUBST(MONGOC_ENABLE_SASL_GSSAPI, 0) AC_SUBST(MONGOC_ENABLE_SASL_SSPI, 0) AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) fi mongodb-1.3.4/src/libmongoc/build/autotools/CheckSnappy.m40000664000175000017500000000172713210321137023346 0ustar jmikolajmikola# If --with-snappy=auto, determine if there is a system installed snappy # greater than our required version. found_snappy=no AS_IF([test "x${with_snappy}" = xauto -o "x${with_snappy}" = xsystem], [ PKG_CHECK_MODULES(SNAPPY, [snappy], [ found_snappy=yes ], [ # If we didn't find snappy with pkgconfig, search manually. If that # fails and with-snappy=system, fail. AC_CHECK_LIB([snappy], [snappy_uncompress], [ AC_CHECK_HEADER([snappy-c.h], [ found_snappy=yes ]) ]) ]) ]) AS_IF([test "x${found_snappy}" = xyes], [ with_snappy=system SNAPPY_LIBS=-lsnappy ], [ # snappy not found AS_IF([test "x${with_snappy}" = xsystem], [ AC_MSG_ERROR([Cannot find system installed snappy. try --with-snappy=no]) ]) with_snappy=no ]) if test "x${with_snappy}" != "xno"; then AC_SUBST(MONGOC_ENABLE_COMPRESSION_SNAPPY, 1) else AC_SUBST(MONGOC_ENABLE_COMPRESSION_SNAPPY, 0) fi AC_SUBST(SNAPPY_LIBS) mongodb-1.3.4/src/libmongoc/build/autotools/CheckTarget.m40000664000175000017500000000114713210321137023316 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.3.4/src/libmongoc/build/autotools/CheckZlib.m40000664000175000017500000000300713210321137022765 0ustar jmikolajmikola# If --with-zlib=auto, determine if there is a system installed zlib # greater than our required version. found_zlib=no AS_IF([test "x${with_zlib}" = xauto -o "x${with_zlib}" = xsystem], [ PKG_CHECK_MODULES(zlib, [zlib], [ found_zlib=yes ], [ # If we didn't find zlib with pkgconfig, search manually. If that # fails and with-zlib=system, fail, or if with-zlib=auto, use # bundled. AC_CHECK_LIB([zlib], [compress2], [ AC_CHECK_HEADER([zlib.h], [ found_zlib=yes ]) ]) ]) ], [ AS_IF([test "x${with_zlib}" != xbundled -a "x${with_zlib}" != xno], [ AC_MSG_ERROR([Invalid --with-zlib option: must be system, bundled, auto, or no.]) ]) ]) AS_IF([test "x${found_zlib}" = "xyes"], [ with_zlib=system ZLIB_LIBS=-lz ], [ # zlib not found AS_IF([test "x${with_zlib}" = xauto -o "x${with_zlib}" = xbundled], [ with_zlib=bundled ], [ AS_IF([test "x${with_zlib}" = xno], [], [ # zlib not found, with-zlib=system AC_MSG_ERROR([Cannot find system installed zlib. try --with-zlib=bundled]) ]) ]) ]) # If we are using the bundled zlib, recurse into its configure. AS_IF([test "x${with_zlib}" = xbundled],[ AC_MSG_CHECKING(whether to enable bundled zlib) AC_MSG_RESULT(yes) ZLIB_LIBS= ZLIB_CFLAGS="-Isrc/zlib-1.2.11" ]) if test "x${with_zlib}" != "xno"; then AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZLIB, 1) else AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZLIB, 0) fi AC_SUBST(ZLIB_LIBS) AC_SUBST(ZLIB_CFLAGS) mongodb-1.3.4/src/libmongoc/build/autotools/Coverage.m40000664000175000017500000000032013210321137022655 0ustar jmikolajmikolaCOVERAGE_CFLAGS="" COVERAGE_LDFLAGS="" if test "$enable_coverage" = "yes"; then COVERAGE_CFLAGS="--coverage -g" COVERAGE_LDFLAGS="--coverage" fi AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_LDFLAGS) mongodb-1.3.4/src/libmongoc/build/autotools/FindDependencies.m40000664000175000017500000000216013210321137024315 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]) AS_IF([test "$enable_rdtscp" = "yes"], [CPPFLAGS="$CPPFLAGS -DENABLE_RDTSCP"]) AS_IF([test "$enable_shm_counters" = "yes"], [CPPFLAGS="$CPPFLAGS -DMONGOC_ENABLE_SHM_COUNTERS"]) AC_CHECK_TYPE([socklen_t], [AC_SUBST(MONGOC_HAVE_SOCKLEN, 1)], [AC_SUBST(MONGOC_HAVE_SOCKLEN, 0)], [#include ]) AX_PTHREAD mongodb-1.3.4/src/libmongoc/build/autotools/Libbson.m40000664000175000017500000000215613210321137022523 0ustar jmikolajmikola# If --with-libbson=auto, determine if there is a system installed libbson # greater than our required version. AS_IF([test "x${with_libbson}" = xauto], [PKG_CHECK_MODULES(BSON, [libbson-1.0 >= 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.3.4/src/libmongoc/build/autotools/MaintainerFlags.m40000664000175000017500000000144013210321137024172 0ustar jmikolajmikolaAS_IF( [test "x$enable_maintainer_flags" = "xyes" && test "x$GCC" = "xyes"], [ # clang only warns if it doesn't support a warning option, turn it into an # error so we really know if whether it supports it. AX_CHECK_COMPILE_FLAG( "-Werror=unknown-warning-option", [WERROR_UNKNOWN_OPTION="-Werror=unknown-warning-option"], [WERROR_UNKNOWN_OPTION=""]) # Read maintainer-flags.txt and apply each flag that the compiler supports. m4_foreach([MAINTAINER_FLAG], m4_split(m4_normalize(m4_esyscmd(cat build/maintainer-flags.txt))), [ AX_CHECK_COMPILE_FLAG( MAINTAINER_FLAG, [MAINTAINER_CFLAGS="$MAINTAINER_CFLAGS MAINTAINER_FLAG"], [], [$WERROR_UNKNOWN_OPTION]) ]) ] AC_SUBST(MAINTAINER_CFLAGS) ) mongodb-1.3.4/src/libmongoc/build/autotools/Optimizations.m40000664000175000017500000000134013210321137023776 0ustar jmikolajmikolaOPTIMIZE_CFLAGS="" OPTIMIZE_LDFLAGS="" AC_DEFUN([check_link_flag], [AX_CHECK_LINK_FLAG([$1], [$2], [$3], [-Werror $4])]) 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_tracing" = "yes"], [CPPFLAGS="$CPPFLAGS -DMONGOC_TRACE"]) mongodb-1.3.4/src/libmongoc/build/autotools/PlatformFlags.m40000664000175000017500000000155313210321137023674 0ustar jmikolajmikoladnl Ignore OpenSSL deprecation warnings on OSX AS_IF([test "$os_darwin" = "yes"], [AX_CHECK_COMPILE_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"], [AX_CHECK_COMPILE_FLAG([-Wno-cast-align], [CFLAGS="$CFLAGS -Wno-cast-align"])]) AS_IF([test "$os_darwin" = "yes"], [AX_CHECK_COMPILE_FLAG([-Wno-unneeded-internal-declaration], [CFLAGS="$CFLAGS -Wno-unneeded-internal-declaration"])]) AS_IF([test "$os_darwin" = "yes"], [AX_CHECK_COMPILE_FLAG([-Wno-error=unused-command-line-argument], [CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument"])]) dnl We know there are some cast-align issues on Solaris AS_IF([test "$os_solaris" = "yes"], [AX_CHECK_COMPILE_FLAG([-Wno-cast-align], [CFLAGS="$CFLAGS -Wno-cast-align"])]) mongodb-1.3.4/src/libmongoc/build/autotools/PrintBuildConfiguration.m40000664000175000017500000000401013210321137025726 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 if test x"${enable_automatic_init_and_cleanup}" != x"no"; then automatic_init_deprecated=" DEPRECATED: use --disable-automatic-init-and-cleanup" fi if test "x$MONGOC_36_EXPERIMENT" = "xyes"; then experimental_features=" Feature #1 : ${enable_feature_1}" 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 init and cleanup : ${enable_automatic_init_and_cleanup}${automatic_init_deprecated} Enable maintainer flags : ${enable_maintainer_flags} 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} Snappy Compression : ${with_snappy} Zlib Compression : ${with_zlib} Libbson : ${with_libbson} ${experimental_features} Documentation: man : ${enable_man_pages} HTML : ${enable_html_docs} " mongodb-1.3.4/src/libmongoc/build/autotools/ReadCommandLineArguments.m40000664000175000017500000001225113210321137026000 0ustar jmikolajmikolaAC_MSG_CHECKING([whether to do a debug build]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [disable optimizations @<:@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], [very verbose debug output @<:@default=no@:>@]), [],[enable_tracing="no"]) AC_MSG_RESULT([$enable_tracing]) AC_MSG_CHECKING([whether to automatic init and cleanup]) AC_ARG_ENABLE(automatic-init-and-cleanup, AC_HELP_STRING([--enable-automatic-init-and-cleanup], [call mongoc_init() and mongoc_cleanup() automatically - DEPRECATED @<:@default=yes@:>@]), [],[enable_automatic_init_and_cleanup="yes"]) AC_MSG_RESULT([$enable_automatic_init_and_cleanup]) 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], [enable debug symbols @<:@default=yes for debug builds, otherwise no@:>@]), [ case "$enable_debug_symbols" in yes) enable_debug_symbols="full" ;; no|min|full) ;; *) AC_MSG_ERROR([Invalid debug symbols option: must be yes, no, or min.]) ;; 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@:>@], [fast performance counters on Intel using the RDTSCP instruction @<:@default=no@:>@])], [], [enable_rdtscp=no]) # use strict compiler flags only on development releases AS_IF([test "x$MONGOC_PRERELEASE_VERSION" != "x"], [maintainer_flags_default=yes], [maintainer_flags_default=no]) AC_ARG_ENABLE([maintainer-flags], [AS_HELP_STRING([--enable-maintainer-flags=@<:@no/yes@:>@], [use strict compiler checks @<:@default=no for release builds, yes for prereleases@:>@])], [], 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 -a "x$with_libbson" != xsystem -a "x$with_libbson" != xauto], [AC_MSG_ERROR([Invalid --with-libbson option: must be system, bundled, or auto])]) AC_ARG_WITH(snappy, AC_HELP_STRING([--with-snappy=@<:@auto/yes/no@:>@], [use system installed snappy. default=auto]), [], [with_snappy=auto]) AS_IF([test "x$with_snappy" != xyes -a "x$with_snappy" != xsystem -a "x$with_snappy" != xauto -a "x$with_snappy" != xno], [AC_MSG_ERROR([Invalid --with-snappy option: must be auto, yes, or no])]) AC_ARG_WITH(zlib, AC_HELP_STRING([--with-zlib=@<:@auto/system/bundled/no@:>@], [use system installed zlib or bundled zlib. default=auto]), [], [with_zlib=auto]) AS_IF([test "x$with_zlib" != xbundled -a "x$with_zlib" != xsystem -a "x$with_zlib" != xauto -a "x$with_zlib" != xno], [AC_MSG_ERROR([Invalid --with-zlib option: must be system, bundled, auto, no])]) AC_ARG_ENABLE([html-docs], [AS_HELP_STRING([--enable-html-docs=@<:@yes/no@:>@], [build HTML documentation @<:@default=no@:>@])], [], [enable_html_docs=no]) AC_ARG_ENABLE([man-pages], [AS_HELP_STRING([--enable-man-pages=@<:@yes/no@:>@], [build and install man pages @<:@default=no@:>@])], [], [enable_man_pages=no]) AC_ARG_ENABLE([examples], [AS_HELP_STRING([--enable-examples=@<:@yes/no@:>@], [build MongoDB C Driver example programs])], [], [enable_examples=yes]) AC_ARG_ENABLE([tests], [AS_HELP_STRING([--enable-tests=@<:@yes/no@:>@], [build MongoDB C Driver tests])], [], [enable_tests=yes]) mongodb-1.3.4/src/libmongoc/build/autotools/SetupAutomake.m40000664000175000017500000000403113210321137023714 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"]) AM_CONDITIONAL([ENABLE_STATIC],[test "$enable_static" = "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 compile the bundled zlib AM_CONDITIONAL([WITH_ZLIB],[test "$with_zlib" = "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"]) AS_IF([test "$enable_man_pages" = "yes" && test -z "$SPHINX_BUILD"], [AC_MSG_ERROR([The Sphinx Python package must be installed to generate man pages.])]) # Should we build HTML documentation AM_CONDITIONAL([ENABLE_HTML_DOCS],[test "$enable_html_docs" = "yes"]) AS_IF([test "$enable_html_docs" = "yes" && test -z "$SPHINX_BUILD"], [AC_MSG_ERROR([The Sphinx Python package must be installed to generate HTML documentation.])]) mongodb-1.3.4/src/libmongoc/build/autotools/SetupLibtool.m40000664000175000017500000000011113210321137023545 0ustar jmikolajmikolaLT_PREREQ([2.2]) AC_DISABLE_STATIC AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL mongodb-1.3.4/src/libmongoc/build/autotools/Versions.m40000664000175000017500000000374413210321137022747 0ustar jmikolajmikolaMONGOC_CURRENT_FILE=${srcdir}/VERSION_CURRENT MONGOC_VERSION=$(cat $MONGOC_CURRENT_FILE) # Ensure newline for "cut" implementations that need it, e.g. HP-UX. MONGOC_MAJOR_VERSION=$( (cat $MONGOC_CURRENT_FILE; echo) | cut -d- -f1 | cut -d. -f1 ) MONGOC_MINOR_VERSION=$( (cat $MONGOC_CURRENT_FILE; echo) | cut -d- -f1 | cut -d. -f2 ) MONGOC_MICRO_VERSION=$( (cat $MONGOC_CURRENT_FILE; echo) | cut -d- -f1 | 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.3.4/src/libmongoc/build/autotools/WeakSymbols.m40000664000175000017500000000040113210321137023362 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.3.4/src/libmongoc/src/mongoc/mongoc-apm-private.h0000664000175000017500000001260213210321137023465 0ustar jmikolajmikola/* * Copyright 2016 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_APM_PRIVATE_H #define MONGOC_APM_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-apm.h" BSON_BEGIN_DECLS struct _mongoc_apm_callbacks_t { mongoc_apm_command_started_cb_t started; mongoc_apm_command_succeeded_cb_t succeeded; mongoc_apm_command_failed_cb_t failed; mongoc_apm_server_changed_cb_t server_changed; mongoc_apm_server_opening_cb_t server_opening; mongoc_apm_server_closed_cb_t server_closed; mongoc_apm_topology_changed_cb_t topology_changed; mongoc_apm_topology_opening_cb_t topology_opening; mongoc_apm_topology_closed_cb_t topology_closed; mongoc_apm_server_heartbeat_started_cb_t server_heartbeat_started; mongoc_apm_server_heartbeat_succeeded_cb_t server_heartbeat_succeeded; mongoc_apm_server_heartbeat_failed_cb_t server_heartbeat_failed; }; /* * command monitoring events */ struct _mongoc_apm_command_started_t { bson_t *command; bool command_owned; const char *database_name; const char *command_name; int64_t request_id; int64_t operation_id; const mongoc_host_list_t *host; uint32_t server_id; void *context; }; struct _mongoc_apm_command_succeeded_t { int64_t duration; const bson_t *reply; const char *command_name; int64_t request_id; int64_t operation_id; const mongoc_host_list_t *host; uint32_t server_id; void *context; }; struct _mongoc_apm_command_failed_t { int64_t duration; const char *command_name; const bson_error_t *error; int64_t request_id; int64_t operation_id; const mongoc_host_list_t *host; uint32_t server_id; void *context; }; /* * SDAM monitoring events */ struct _mongoc_apm_server_changed_t { const mongoc_host_list_t *host; bson_oid_t topology_id; const mongoc_server_description_t *previous_description; const mongoc_server_description_t *new_description; void *context; }; struct _mongoc_apm_server_opening_t { const mongoc_host_list_t *host; bson_oid_t topology_id; void *context; }; struct _mongoc_apm_server_closed_t { const mongoc_host_list_t *host; bson_oid_t topology_id; void *context; }; struct _mongoc_apm_topology_changed_t { bson_oid_t topology_id; const mongoc_topology_description_t *previous_description; const mongoc_topology_description_t *new_description; void *context; }; struct _mongoc_apm_topology_opening_t { bson_oid_t topology_id; void *context; }; struct _mongoc_apm_topology_closed_t { bson_oid_t topology_id; void *context; }; struct _mongoc_apm_server_heartbeat_started_t { const mongoc_host_list_t *host; void *context; }; struct _mongoc_apm_server_heartbeat_succeeded_t { int64_t duration_usec; const bson_t *reply; const mongoc_host_list_t *host; void *context; }; struct _mongoc_apm_server_heartbeat_failed_t { int64_t duration_usec; const bson_error_t *error; const mongoc_host_list_t *host; void *context; }; void mongoc_apm_command_started_init (mongoc_apm_command_started_t *event, const bson_t *command, const char *database_name, const char *command_name, int64_t request_id, int64_t operation_id, const mongoc_host_list_t *host, uint32_t server_id, void *context); void mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event); void mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event, int64_t duration, const bson_t *reply, const char *command_name, int64_t request_id, int64_t operation_id, const mongoc_host_list_t *host, uint32_t server_id, void *context); void mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event); void mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event, int64_t duration, const char *command_name, const bson_error_t *error, int64_t request_id, int64_t operation_id, const mongoc_host_list_t *host, uint32_t server_id, void *context); void mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event); BSON_END_DECLS #endif /* MONGOC_APM_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-apm.c0000664000175000017500000003621113210321137022012 0ustar jmikolajmikola/* * Copyright 2016 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-apm-private.h" /* * An Application Performance Management (APM) implementation, complying with * MongoDB's Command Monitoring Spec: * * https://github.com/mongodb/specifications/tree/master/source/command-monitoring */ /* * Private initializer / cleanup functions. */ void mongoc_apm_command_started_init (mongoc_apm_command_started_t *event, const bson_t *command, const char *database_name, const char *command_name, int64_t request_id, int64_t operation_id, const mongoc_host_list_t *host, uint32_t server_id, void *context) { bson_iter_t iter; uint32_t len; const uint8_t *data; /* Command Monitoring Spec: * * In cases where queries or commands are embedded in a $query parameter * when a read preference is provided, they MUST be unwrapped and the value * of the $query attribute becomes the filter or the command in the started * event. The read preference will subsequently be dropped as it is * considered metadata and metadata is not currently provided in the command * events. */ if (bson_has_field (command, "$readPreference")) { if (bson_iter_init_find (&iter, command, "$query") && BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_iter_document (&iter, &len, &data); event->command = bson_new_from_data (data, len); } else { /* $query should exist, but user could provide us a misformatted doc */ event->command = bson_new (); } event->command_owned = true; } else { /* discard "const", we promise not to modify "command" */ event->command = (bson_t *) command; event->command_owned = false; } event->database_name = database_name; event->command_name = command_name; event->request_id = request_id; event->operation_id = operation_id; event->host = host; event->server_id = server_id; event->context = context; } void mongoc_apm_command_started_cleanup (mongoc_apm_command_started_t *event) { if (event->command_owned) { bson_destroy (event->command); } } void mongoc_apm_command_succeeded_init (mongoc_apm_command_succeeded_t *event, int64_t duration, const bson_t *reply, const char *command_name, int64_t request_id, int64_t operation_id, const mongoc_host_list_t *host, uint32_t server_id, void *context) { BSON_ASSERT (reply); event->duration = duration; event->reply = reply; event->command_name = command_name; event->request_id = request_id; event->operation_id = operation_id; event->host = host; event->server_id = server_id; event->context = context; } void mongoc_apm_command_succeeded_cleanup (mongoc_apm_command_succeeded_t *event) { /* no-op */ } void mongoc_apm_command_failed_init (mongoc_apm_command_failed_t *event, int64_t duration, const char *command_name, const bson_error_t *error, int64_t request_id, int64_t operation_id, const mongoc_host_list_t *host, uint32_t server_id, void *context) { event->duration = duration; event->command_name = command_name; event->error = error; event->request_id = request_id; event->operation_id = operation_id; event->host = host; event->server_id = server_id; event->context = context; } void mongoc_apm_command_failed_cleanup (mongoc_apm_command_failed_t *event) { /* no-op */ } /* * event field accessors */ /* command-started event fields */ const bson_t * mongoc_apm_command_started_get_command ( const mongoc_apm_command_started_t *event) { return event->command; } const char * mongoc_apm_command_started_get_database_name ( const mongoc_apm_command_started_t *event) { return event->database_name; } const char * mongoc_apm_command_started_get_command_name ( const mongoc_apm_command_started_t *event) { return event->command_name; } int64_t mongoc_apm_command_started_get_request_id ( const mongoc_apm_command_started_t *event) { return event->request_id; } int64_t mongoc_apm_command_started_get_operation_id ( const mongoc_apm_command_started_t *event) { return event->operation_id; } const mongoc_host_list_t * mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event) { return event->host; } uint32_t mongoc_apm_command_started_get_server_id ( const mongoc_apm_command_started_t *event) { return event->server_id; } void * mongoc_apm_command_started_get_context ( const mongoc_apm_command_started_t *event) { return event->context; } /* command-succeeded event fields */ int64_t mongoc_apm_command_succeeded_get_duration ( const mongoc_apm_command_succeeded_t *event) { return event->duration; } const bson_t * mongoc_apm_command_succeeded_get_reply ( const mongoc_apm_command_succeeded_t *event) { return event->reply; } const char * mongoc_apm_command_succeeded_get_command_name ( const mongoc_apm_command_succeeded_t *event) { return event->command_name; } int64_t mongoc_apm_command_succeeded_get_request_id ( const mongoc_apm_command_succeeded_t *event) { return event->request_id; } int64_t mongoc_apm_command_succeeded_get_operation_id ( const mongoc_apm_command_succeeded_t *event) { return event->operation_id; } const mongoc_host_list_t * mongoc_apm_command_succeeded_get_host ( const mongoc_apm_command_succeeded_t *event) { return event->host; } uint32_t mongoc_apm_command_succeeded_get_server_id ( const mongoc_apm_command_succeeded_t *event) { return event->server_id; } void * mongoc_apm_command_succeeded_get_context ( const mongoc_apm_command_succeeded_t *event) { return event->context; } /* command-failed event fields */ int64_t mongoc_apm_command_failed_get_duration ( const mongoc_apm_command_failed_t *event) { return event->duration; } const char * mongoc_apm_command_failed_get_command_name ( const mongoc_apm_command_failed_t *event) { return event->command_name; } void mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event, bson_error_t *error) { memcpy (error, event->error, sizeof *event->error); } int64_t mongoc_apm_command_failed_get_request_id ( const mongoc_apm_command_failed_t *event) { return event->request_id; } int64_t mongoc_apm_command_failed_get_operation_id ( const mongoc_apm_command_failed_t *event) { return event->operation_id; } const mongoc_host_list_t * mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event) { return event->host; } uint32_t mongoc_apm_command_failed_get_server_id ( const mongoc_apm_command_failed_t *event) { return event->server_id; } void * mongoc_apm_command_failed_get_context (const mongoc_apm_command_failed_t *event) { return event->context; } /* server-changed event fields */ const mongoc_host_list_t * mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event) { return event->host; } void mongoc_apm_server_changed_get_topology_id ( const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id) { bson_oid_copy (&event->topology_id, topology_id); } const mongoc_server_description_t * mongoc_apm_server_changed_get_previous_description ( const mongoc_apm_server_changed_t *event) { return event->previous_description; } const mongoc_server_description_t * mongoc_apm_server_changed_get_new_description ( const mongoc_apm_server_changed_t *event) { return event->new_description; } void * mongoc_apm_server_changed_get_context (const mongoc_apm_server_changed_t *event) { return event->context; } /* server-opening event fields */ const mongoc_host_list_t * mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event) { return event->host; } void mongoc_apm_server_opening_get_topology_id ( const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id) { bson_oid_copy (&event->topology_id, topology_id); } void * mongoc_apm_server_opening_get_context (const mongoc_apm_server_opening_t *event) { return event->context; } /* server-closed event fields */ const mongoc_host_list_t * mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event) { return event->host; } void mongoc_apm_server_closed_get_topology_id ( const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id) { bson_oid_copy (&event->topology_id, topology_id); } void * mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event) { return event->context; } /* topology-changed event fields */ void mongoc_apm_topology_changed_get_topology_id ( const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id) { bson_oid_copy (&event->topology_id, topology_id); } const mongoc_topology_description_t * mongoc_apm_topology_changed_get_previous_description ( const mongoc_apm_topology_changed_t *event) { return event->previous_description; } const mongoc_topology_description_t * mongoc_apm_topology_changed_get_new_description ( const mongoc_apm_topology_changed_t *event) { return event->new_description; } void * mongoc_apm_topology_changed_get_context ( const mongoc_apm_topology_changed_t *event) { return event->context; } /* topology-opening event field */ void mongoc_apm_topology_opening_get_topology_id ( const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id) { bson_oid_copy (&event->topology_id, topology_id); } void * mongoc_apm_topology_opening_get_context ( const mongoc_apm_topology_opening_t *event) { return event->context; } /* topology-closed event field */ void mongoc_apm_topology_closed_get_topology_id ( const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id) { bson_oid_copy (&event->topology_id, topology_id); } void * mongoc_apm_topology_closed_get_context ( const mongoc_apm_topology_closed_t *event) { return event->context; } /* heartbeat-started event field */ const mongoc_host_list_t * mongoc_apm_server_heartbeat_started_get_host ( const mongoc_apm_server_heartbeat_started_t *event) { return event->host; } void * mongoc_apm_server_heartbeat_started_get_context ( const mongoc_apm_server_heartbeat_started_t *event) { return event->context; } /* heartbeat-succeeded event fields */ int64_t mongoc_apm_server_heartbeat_succeeded_get_duration ( const mongoc_apm_server_heartbeat_succeeded_t *event) { return event->duration_usec; } const bson_t * mongoc_apm_server_heartbeat_succeeded_get_reply ( const mongoc_apm_server_heartbeat_succeeded_t *event) { return event->reply; } const mongoc_host_list_t * mongoc_apm_server_heartbeat_succeeded_get_host ( const mongoc_apm_server_heartbeat_succeeded_t *event) { return event->host; } void * mongoc_apm_server_heartbeat_succeeded_get_context ( const mongoc_apm_server_heartbeat_succeeded_t *event) { return event->context; } /* heartbeat-failed event fields */ int64_t mongoc_apm_server_heartbeat_failed_get_duration ( const mongoc_apm_server_heartbeat_failed_t *event) { return event->duration_usec; } void mongoc_apm_server_heartbeat_failed_get_error ( const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error) { memcpy (error, event->error, sizeof *event->error); } const mongoc_host_list_t * mongoc_apm_server_heartbeat_failed_get_host ( const mongoc_apm_server_heartbeat_failed_t *event) { return event->host; } void * mongoc_apm_server_heartbeat_failed_get_context ( const mongoc_apm_server_heartbeat_failed_t *event) { return event->context; } /* * registering callbacks */ mongoc_apm_callbacks_t * mongoc_apm_callbacks_new (void) { size_t s = sizeof (mongoc_apm_callbacks_t); return (mongoc_apm_callbacks_t *) bson_malloc0 (s); } void mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks) { bson_free (callbacks); } void mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_command_started_cb_t cb) { callbacks->started = cb; } void mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_command_succeeded_cb_t cb) { callbacks->succeeded = cb; } void mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_command_failed_cb_t cb) { callbacks->failed = cb; } void mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_changed_cb_t cb) { callbacks->server_changed = cb; } void mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_opening_cb_t cb) { callbacks->server_opening = cb; } void mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_closed_cb_t cb) { callbacks->server_closed = cb; } void mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_topology_changed_cb_t cb) { callbacks->topology_changed = cb; } void mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_topology_opening_cb_t cb) { callbacks->topology_opening = cb; } void mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_topology_closed_cb_t cb) { callbacks->topology_closed = cb; } void mongoc_apm_set_server_heartbeat_started_cb ( mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_heartbeat_started_cb_t cb) { callbacks->server_heartbeat_started = cb; } void mongoc_apm_set_server_heartbeat_succeeded_cb ( mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_heartbeat_succeeded_cb_t cb) { callbacks->server_heartbeat_succeeded = cb; } void mongoc_apm_set_server_heartbeat_failed_cb ( mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_heartbeat_failed_cb_t cb) { callbacks->server_heartbeat_failed = cb; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-apm.h0000664000175000017500000003151413210321137022020 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_APM_H #define MONGOC_APM_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-macros.h" #include "mongoc-host-list.h" #include "mongoc-server-description.h" #include "mongoc-topology-description.h" BSON_BEGIN_DECLS /* * Application Performance Management (APM) interface, complies with two specs. * MongoDB's Command Monitoring Spec: * * https://github.com/mongodb/specifications/tree/master/source/command-monitoring * * MongoDB's Spec for Monitoring Server Discovery and Monitoring (SDAM) events: * * https://github.com/mongodb/specifications/tree/master/source/server-discovery-and-monitoring * */ /* * callbacks to receive APM events */ typedef struct _mongoc_apm_callbacks_t mongoc_apm_callbacks_t; /* * command monitoring events */ typedef struct _mongoc_apm_command_started_t mongoc_apm_command_started_t; typedef struct _mongoc_apm_command_succeeded_t mongoc_apm_command_succeeded_t; typedef struct _mongoc_apm_command_failed_t mongoc_apm_command_failed_t; /* * SDAM monitoring events */ typedef struct _mongoc_apm_server_changed_t mongoc_apm_server_changed_t; typedef struct _mongoc_apm_server_opening_t mongoc_apm_server_opening_t; typedef struct _mongoc_apm_server_closed_t mongoc_apm_server_closed_t; typedef struct _mongoc_apm_topology_changed_t mongoc_apm_topology_changed_t; typedef struct _mongoc_apm_topology_opening_t mongoc_apm_topology_opening_t; typedef struct _mongoc_apm_topology_closed_t mongoc_apm_topology_closed_t; typedef struct _mongoc_apm_server_heartbeat_started_t mongoc_apm_server_heartbeat_started_t; typedef struct _mongoc_apm_server_heartbeat_succeeded_t mongoc_apm_server_heartbeat_succeeded_t; typedef struct _mongoc_apm_server_heartbeat_failed_t mongoc_apm_server_heartbeat_failed_t; /* * event field accessors */ /* command-started event fields */ MONGOC_EXPORT (const bson_t *) mongoc_apm_command_started_get_command ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (const char *) mongoc_apm_command_started_get_database_name ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (const char *) mongoc_apm_command_started_get_command_name ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (int64_t) mongoc_apm_command_started_get_request_id ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (int64_t) mongoc_apm_command_started_get_operation_id ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_command_started_get_host (const mongoc_apm_command_started_t *event); MONGOC_EXPORT (uint32_t) mongoc_apm_command_started_get_server_id ( const mongoc_apm_command_started_t *event); MONGOC_EXPORT (void *) mongoc_apm_command_started_get_context ( const mongoc_apm_command_started_t *event); /* command-succeeded event fields */ MONGOC_EXPORT (int64_t) mongoc_apm_command_succeeded_get_duration ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (const bson_t *) mongoc_apm_command_succeeded_get_reply ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (const char *) mongoc_apm_command_succeeded_get_command_name ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (int64_t) mongoc_apm_command_succeeded_get_request_id ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (int64_t) mongoc_apm_command_succeeded_get_operation_id ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_command_succeeded_get_host ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (uint32_t) mongoc_apm_command_succeeded_get_server_id ( const mongoc_apm_command_succeeded_t *event); MONGOC_EXPORT (void *) mongoc_apm_command_succeeded_get_context ( const mongoc_apm_command_succeeded_t *event); /* command-failed event fields */ MONGOC_EXPORT (int64_t) mongoc_apm_command_failed_get_duration ( const mongoc_apm_command_failed_t *event); MONGOC_EXPORT (const char *) mongoc_apm_command_failed_get_command_name ( const mongoc_apm_command_failed_t *event); /* retrieve the error by filling out the passed-in "error" struct */ MONGOC_EXPORT (void) mongoc_apm_command_failed_get_error (const mongoc_apm_command_failed_t *event, bson_error_t *error); MONGOC_EXPORT (int64_t) mongoc_apm_command_failed_get_request_id ( const mongoc_apm_command_failed_t *event); MONGOC_EXPORT (int64_t) mongoc_apm_command_failed_get_operation_id ( const mongoc_apm_command_failed_t *event); MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_command_failed_get_host (const mongoc_apm_command_failed_t *event); MONGOC_EXPORT (uint32_t) mongoc_apm_command_failed_get_server_id ( const mongoc_apm_command_failed_t *event); MONGOC_EXPORT (void *) mongoc_apm_command_failed_get_context ( const mongoc_apm_command_failed_t *event); /* server-changed event fields */ MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_server_changed_get_host (const mongoc_apm_server_changed_t *event); MONGOC_EXPORT (void) mongoc_apm_server_changed_get_topology_id ( const mongoc_apm_server_changed_t *event, bson_oid_t *topology_id); MONGOC_EXPORT (const mongoc_server_description_t *) mongoc_apm_server_changed_get_previous_description ( const mongoc_apm_server_changed_t *event); MONGOC_EXPORT (const mongoc_server_description_t *) mongoc_apm_server_changed_get_new_description ( const mongoc_apm_server_changed_t *event); MONGOC_EXPORT (void *) mongoc_apm_server_changed_get_context ( const mongoc_apm_server_changed_t *event); /* server-opening event fields */ MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_server_opening_get_host (const mongoc_apm_server_opening_t *event); MONGOC_EXPORT (void) mongoc_apm_server_opening_get_topology_id ( const mongoc_apm_server_opening_t *event, bson_oid_t *topology_id); MONGOC_EXPORT (void *) mongoc_apm_server_opening_get_context ( const mongoc_apm_server_opening_t *event); /* server-closed event fields */ MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_server_closed_get_host (const mongoc_apm_server_closed_t *event); MONGOC_EXPORT (void) mongoc_apm_server_closed_get_topology_id ( const mongoc_apm_server_closed_t *event, bson_oid_t *topology_id); MONGOC_EXPORT (void *) mongoc_apm_server_closed_get_context (const mongoc_apm_server_closed_t *event); /* topology-changed event fields */ MONGOC_EXPORT (void) mongoc_apm_topology_changed_get_topology_id ( const mongoc_apm_topology_changed_t *event, bson_oid_t *topology_id); MONGOC_EXPORT (const mongoc_topology_description_t *) mongoc_apm_topology_changed_get_previous_description ( const mongoc_apm_topology_changed_t *event); MONGOC_EXPORT (const mongoc_topology_description_t *) mongoc_apm_topology_changed_get_new_description ( const mongoc_apm_topology_changed_t *event); MONGOC_EXPORT (void *) mongoc_apm_topology_changed_get_context ( const mongoc_apm_topology_changed_t *event); /* topology-opening event field */ MONGOC_EXPORT (void) mongoc_apm_topology_opening_get_topology_id ( const mongoc_apm_topology_opening_t *event, bson_oid_t *topology_id); MONGOC_EXPORT (void *) mongoc_apm_topology_opening_get_context ( const mongoc_apm_topology_opening_t *event); /* topology-closed event field */ MONGOC_EXPORT (void) mongoc_apm_topology_closed_get_topology_id ( const mongoc_apm_topology_closed_t *event, bson_oid_t *topology_id); MONGOC_EXPORT (void *) mongoc_apm_topology_closed_get_context ( const mongoc_apm_topology_closed_t *event); /* heartbeat-started event field */ MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_server_heartbeat_started_get_host ( const mongoc_apm_server_heartbeat_started_t *event); MONGOC_EXPORT (void *) mongoc_apm_server_heartbeat_started_get_context ( const mongoc_apm_server_heartbeat_started_t *event); /* heartbeat-succeeded event fields */ MONGOC_EXPORT (int64_t) mongoc_apm_server_heartbeat_succeeded_get_duration ( const mongoc_apm_server_heartbeat_succeeded_t *event); MONGOC_EXPORT (const bson_t *) mongoc_apm_server_heartbeat_succeeded_get_reply ( const mongoc_apm_server_heartbeat_succeeded_t *event); MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_server_heartbeat_succeeded_get_host ( const mongoc_apm_server_heartbeat_succeeded_t *event); MONGOC_EXPORT (void *) mongoc_apm_server_heartbeat_succeeded_get_context ( const mongoc_apm_server_heartbeat_succeeded_t *event); /* heartbeat-failed event fields */ MONGOC_EXPORT (int64_t) mongoc_apm_server_heartbeat_failed_get_duration ( const mongoc_apm_server_heartbeat_failed_t *event); MONGOC_EXPORT (void) mongoc_apm_server_heartbeat_failed_get_error ( const mongoc_apm_server_heartbeat_failed_t *event, bson_error_t *error); MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_apm_server_heartbeat_failed_get_host ( const mongoc_apm_server_heartbeat_failed_t *event); MONGOC_EXPORT (void *) mongoc_apm_server_heartbeat_failed_get_context ( const mongoc_apm_server_heartbeat_failed_t *event); /* * callbacks */ typedef void (*mongoc_apm_command_started_cb_t) ( const mongoc_apm_command_started_t *event); typedef void (*mongoc_apm_command_succeeded_cb_t) ( const mongoc_apm_command_succeeded_t *event); typedef void (*mongoc_apm_command_failed_cb_t) ( const mongoc_apm_command_failed_t *event); typedef void (*mongoc_apm_server_changed_cb_t) ( const mongoc_apm_server_changed_t *event); typedef void (*mongoc_apm_server_opening_cb_t) ( const mongoc_apm_server_opening_t *event); typedef void (*mongoc_apm_server_closed_cb_t) ( const mongoc_apm_server_closed_t *event); typedef void (*mongoc_apm_topology_changed_cb_t) ( const mongoc_apm_topology_changed_t *event); typedef void (*mongoc_apm_topology_opening_cb_t) ( const mongoc_apm_topology_opening_t *event); typedef void (*mongoc_apm_topology_closed_cb_t) ( const mongoc_apm_topology_closed_t *event); typedef void (*mongoc_apm_server_heartbeat_started_cb_t) ( const mongoc_apm_server_heartbeat_started_t *event); typedef void (*mongoc_apm_server_heartbeat_succeeded_cb_t) ( const mongoc_apm_server_heartbeat_succeeded_t *event); typedef void (*mongoc_apm_server_heartbeat_failed_cb_t) ( const mongoc_apm_server_heartbeat_failed_t *event); /* * registering callbacks */ MONGOC_EXPORT (mongoc_apm_callbacks_t *) mongoc_apm_callbacks_new (void); MONGOC_EXPORT (void) mongoc_apm_callbacks_destroy (mongoc_apm_callbacks_t *callbacks); MONGOC_EXPORT (void) mongoc_apm_set_command_started_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_command_started_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_command_succeeded_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_command_succeeded_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_command_failed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_command_failed_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_server_changed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_changed_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_server_opening_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_opening_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_server_closed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_closed_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_topology_changed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_topology_changed_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_topology_opening_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_topology_opening_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_topology_closed_cb (mongoc_apm_callbacks_t *callbacks, mongoc_apm_topology_closed_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_server_heartbeat_started_cb ( mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_heartbeat_started_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_server_heartbeat_succeeded_cb ( mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_heartbeat_succeeded_cb_t cb); MONGOC_EXPORT (void) mongoc_apm_set_server_heartbeat_failed_cb ( mongoc_apm_callbacks_t *callbacks, mongoc_apm_server_heartbeat_failed_cb_t cb); BSON_END_DECLS #endif /* MONGOC_APM_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-array-private.h0000664000175000017500000000276613210321137024040 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_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.3.4/src/libmongoc/src/mongoc/mongoc-array.c0000664000175000017500000000442313210321137022353 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.3.4/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h0000664000175000017500000000526713210321137024577 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_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 connect_started; int64_t cmd_started; int64_t timeout_msec; 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, int64_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.3.4/src/libmongoc/src/mongoc/mongoc-async-cmd.c0000664000175000017500000002607313210321137023120 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 "mongoc-log.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; int retry_events = 0; for (tls_stream = stream; tls_stream->type != MONGOC_STREAM_TLS; tls_stream = mongoc_stream_get_base_stream (tls_stream)) { } if (mongoc_stream_tls_handshake ( tls_stream, host, timeout_msec, &retry_events, error)) { return 1; } if (retry_events) { *events = retry_events; return 0; } return -1; } #endif bool mongoc_async_cmd_run (mongoc_async_cmd_t *acmd) { mongoc_async_cmd_result_t result; int64_t rtt_msec; _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_msec = (bson_get_monotonic_time () - acmd->cmd_started) / 1000; if (result == MONGOC_ASYNC_CMD_SUCCESS) { acmd->cb (result, &acmd->reply, rtt_msec, acmd->data, &acmd->error); } else { /* we're in ERROR, TIMEOUT, or CANCELED */ acmd->cb (result, NULL, rtt_msec, 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.header.msg_len = 0; acmd->rpc.header.request_id = ++acmd->async->request_id; acmd->rpc.header.response_to = 0; acmd->rpc.header.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; /* This will always be isMaster, which are not allowed to be compressed */ _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, int64_t timeout_msec) { mongoc_async_cmd_t *acmd; BSON_ASSERT (cmd); BSON_ASSERT (dbname); BSON_ASSERT (stream); acmd = (mongoc_async_cmd_t *) bson_malloc0 (sizeof (*acmd)); acmd->async = async; acmd->timeout_msec = timeout_msec; acmd->stream = stream; acmd->setup = setup; acmd->setup_ctx = setup_ctx; acmd->cb = cb; acmd->data = cb_data; acmd->connect_started = bson_get_monotonic_time (); 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); async->ncmds++; 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) { int retval; BSON_ASSERT (acmd->timeout_msec < INT32_MAX); retval = acmd->setup (acmd->stream, &acmd->events, acmd->setup_ctx, (int32_t) acmd->timeout_msec, &acmd->error); switch (retval) { case -1: return MONGOC_ASYNC_CMD_ERROR; 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->cmd_started = 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); 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); 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; } if (BSON_UINT32_FROM_LE (acmd->rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) { uint8_t *buf = NULL; size_t len = BSON_UINT32_FROM_LE (acmd->rpc.compressed.uncompressed_size) + sizeof (mongoc_rpc_header_t); buf = bson_malloc0 (len); if (!_mongoc_rpc_decompress (&acmd->rpc, buf, len)) { bson_free (buf); bson_set_error (&acmd->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Could not decompress server reply"); return MONGOC_ASYNC_CMD_ERROR; } _mongoc_buffer_destroy (&acmd->buffer); _mongoc_buffer_init (&acmd->buffer, buf, len, NULL, NULL); } _mongoc_rpc_swab_from_le (&acmd->rpc); if (!_mongoc_rpc_get_first_document (&acmd->rpc, &acmd->reply)) { bson_set_error (&acmd->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply from server"); return MONGOC_ASYNC_CMD_ERROR; } acmd->reply_needs_cleanup = true; return MONGOC_ASYNC_CMD_SUCCESS; } return MONGOC_ASYNC_CMD_IN_PROGRESS; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-async-private.h0000664000175000017500000000360413210321137024027 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_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); void mongoc_async_run (mongoc_async_t *async); BSON_END_DECLS #endif /* MONGOC_ASYNC_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-async.c0000664000175000017500000001106213210321137022347 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" #include "mongoc.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "async" 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); } void mongoc_async_run (mongoc_async_t *async) { mongoc_async_cmd_t *acmd, *tmp; mongoc_stream_poll_t *poller = NULL; int i; ssize_t nactive; int64_t now; int64_t expire_at; int64_t poll_timeout_msec; size_t poll_size; now = bson_get_monotonic_time (); poll_size = 0; /* CDRIVER-1571 reset start times in case a stream initiator was slow */ DL_FOREACH (async->cmds, acmd) { acmd->connect_started = now; } while (async->ncmds) { /* ncmds grows if we discover a replica & start calling ismaster on it */ if (poll_size < async->ncmds) { poller = (mongoc_stream_poll_t *) bson_realloc ( poller, sizeof (*poller) * async->ncmds); poll_size = async->ncmds; } i = 0; expire_at = INT64_MAX; DL_FOREACH (async->cmds, acmd) { poller[i].stream = acmd->stream; poller[i].events = acmd->events; poller[i].revents = 0; BSON_ASSERT (acmd->connect_started > 0); expire_at = BSON_MIN ( expire_at, acmd->connect_started + acmd->timeout_msec * 1000); i++; } poll_timeout_msec = BSON_MAX (0, (expire_at - now) / 1000); BSON_ASSERT (poll_timeout_msec < INT32_MAX); nactive = mongoc_stream_poll (poller, async->ncmds, (int32_t) poll_timeout_msec); if (nactive) { i = 0; DL_FOREACH_SAFE (async->cmds, acmd, tmp) { if (poller[i].revents & (POLLERR | POLLHUP)) { int hup = poller[i].revents & POLLHUP; if (acmd->state == MONGOC_ASYNC_CMD_SEND) { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, hup ? "connection refused" : "unknown connection error"); } else { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, hup ? "connection closed" : "unknown socket error"); } acmd->state = MONGOC_ASYNC_CMD_ERROR_STATE; } if ((poller[i].revents & poller[i].events) || acmd->state == MONGOC_ASYNC_CMD_ERROR_STATE) { mongoc_async_cmd_run (acmd); nactive--; } if (!nactive) { break; } i++; } } DL_FOREACH_SAFE (async->cmds, acmd, tmp) { if (now > acmd->connect_started + acmd->timeout_msec * 1000) { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, acmd->state == MONGOC_ASYNC_CMD_SEND ? "connection timeout" : "socket timeout"); acmd->cb (MONGOC_ASYNC_CMD_TIMEOUT, NULL, (now - acmd->connect_started) / 1000, acmd->data, &acmd->error); /* Remove acmd from the async->cmds doubly-linked list */ mongoc_async_cmd_destroy (acmd); } } now = bson_get_monotonic_time (); } if (poll_size) { bson_free (poller); } } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-b64-private.h0000664000175000017500000000207513210321137023306 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_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); int mongoc_b64_pton (char const *src, uint8_t *target, size_t targsize); #endif /* MONGOC_B64_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-b64.c0000664000175000017500000004242413210321137021633 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; } /* (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); } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-buffer-private.h0000664000175000017500000000421113210321137024156 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_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); 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.3.4/src/libmongoc/src/mongoc/mongoc-buffer.c0000664000175000017500000002133013210321137022502 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-private.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: socket error or timeout", (uint64_t) size); 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", (unsigned) min_bytes); 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", (unsigned) buffer->len, (unsigned) min_bytes); 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 * * 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 0 or -1. */ ssize_t _mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, int32_t timeout_msec) { 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.3.4/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h0000664000175000017500000000306013210321137025641 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_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 server_id; mongoc_array_t commands; mongoc_write_result_t result; bool executed; int64_t operation_id; }; 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.3.4/src/libmongoc/src/mongoc/mongoc-bulk-operation.c0000664000175000017500000006131713210321137024175 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-trace-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-util-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->server_id = 0; _mongoc_array_init (&bulk->commands, sizeof (mongoc_write_command_t)); _mongoc_write_result_init (&bulk->result); 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; bulk->operation_id = ++client->cluster.operation_id; 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); } } /* for speed, pre-split batch every 1000 docs. a future server's * maxWriteBatchSize may grow larger than the default, then we'll revise. */ #define SHOULD_APPEND(_write_cmd, _write_cmd_type) \ (((_write_cmd->type) == (_write_cmd_type)) && \ (_write_cmd)->n_documents < MONGOC_DEFAULT_WRITE_BATCH_SIZE) /* already failed, e.g. a bad call to mongoc_bulk_operation_insert? */ #define BULK_EXIT_IF_PRIOR_ERROR \ do { \ if (bulk->result.error.domain) { \ EXIT; \ } \ } while (0) #define BULK_RETURN_IF_PRIOR_ERROR \ do { \ if (bulk->result.error.domain) { \ if (error != &bulk->result.error) { \ bson_set_error (error, \ MONGOC_ERROR_COMMAND, \ MONGOC_ERROR_COMMAND_INVALID_ARG, \ "Bulk operation is invalid from prior error: %s", \ bulk->result.error.message); \ }; \ return false; \ }; \ } while (0) bool _mongoc_bulk_operation_remove_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *opts, bson_error_t *error) /* OUT */ { mongoc_write_command_t command = {0}; mongoc_write_command_t *last; ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (selector); BULK_RETURN_IF_PRIOR_ERROR; if (bulk->commands.len) { last = &_mongoc_array_index ( &bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (SHOULD_APPEND (last, MONGOC_WRITE_COMMAND_DELETE)) { _mongoc_write_command_delete_append (last, selector, opts); RETURN (true); } } _mongoc_write_command_init_delete ( &command, selector, opts, bulk->flags, bulk->operation_id); _mongoc_array_append_val (&bulk->commands, command); RETURN (true); } bool mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *opts, bson_error_t *error) /* OUT */ { bool retval; bson_t opts_dup; bson_iter_t iter; ENTRY; BULK_RETURN_IF_PRIOR_ERROR; if (opts && bson_iter_init_find (&iter, opts, "limit")) { if ((!BSON_ITER_HOLDS_INT (&iter)) || !bson_iter_as_int64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "%s expects the 'limit' option to be 1", BSON_FUNC); RETURN (false); } return _mongoc_bulk_operation_remove_with_opts ( bulk, selector, opts, error); } bson_init (&opts_dup); BSON_APPEND_INT32 (&opts_dup, "limit", 1); if (opts) { bson_concat (&opts_dup, opts); } retval = _mongoc_bulk_operation_remove_with_opts ( bulk, selector, &opts_dup, error); bson_destroy (&opts_dup); RETURN (retval); } bool mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *opts, bson_error_t *error) /* OUT */ { bool retval; bson_t opts_dup; bson_iter_t iter; ENTRY; BULK_RETURN_IF_PRIOR_ERROR; if (opts && bson_iter_init_find (&iter, opts, "limit")) { if ((!BSON_ITER_HOLDS_INT (&iter)) || bson_iter_as_int64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "%s expects the 'limit' option to be 0", BSON_FUNC); RETURN (false); } RETURN ( _mongoc_bulk_operation_remove_with_opts (bulk, selector, opts, error)); } bson_init (&opts_dup); BSON_APPEND_INT32 (&opts_dup, "limit", 0); if (opts) { bson_concat (&opts_dup, opts); } retval = _mongoc_bulk_operation_remove_with_opts ( bulk, selector, &opts_dup, error); bson_destroy (&opts_dup); RETURN (retval); } void mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, /* IN */ const bson_t *selector) /* IN */ { bson_t opts; bson_error_t *error = &bulk->result.error; ENTRY; BULK_EXIT_IF_PRIOR_ERROR; bson_init (&opts); BSON_APPEND_INT32 (&opts, "limit", 0); mongoc_bulk_operation_remove_many_with_opts (bulk, selector, &opts, error); bson_destroy (&opts); if (error->domain) { MONGOC_WARNING ("%s", error->message); } EXIT; } void mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, /* IN */ const bson_t *selector) /* IN */ { bson_t opts; bson_error_t *error = &bulk->result.error; ENTRY; BULK_EXIT_IF_PRIOR_ERROR; bson_init (&opts); BSON_APPEND_INT32 (&opts, "limit", 1); mongoc_bulk_operation_remove_one_with_opts (bulk, selector, &opts, error); bson_destroy (&opts); if (error->domain) { MONGOC_WARNING ("%s", error->message); } 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) { ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (document); if (!mongoc_bulk_operation_insert_with_opts ( bulk, document, NULL /* opts */, &bulk->result.error)) { MONGOC_WARNING ("%s", bulk->result.error.message); } EXIT; } bool mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *document, const bson_t *opts, bson_error_t *error) { mongoc_write_command_t command = {0}; mongoc_write_command_t *last; bson_iter_t iter; ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (document); BULK_RETURN_IF_PRIOR_ERROR; if (opts && bson_iter_init_find_case (&iter, opts, "legacyIndex") && bson_iter_as_bool (&iter)) { if (!_mongoc_validate_legacy_index (document, error)) { return false; } } else if (!_mongoc_validate_new_document (document, error)) { return false; } if (bulk->commands.len) { last = &_mongoc_array_index ( &bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (SHOULD_APPEND (last, MONGOC_WRITE_COMMAND_INSERT)) { _mongoc_write_command_insert_append (last, document); return true; } } _mongoc_write_command_init_insert ( &command, document, bulk->flags, bulk->operation_id, !mongoc_write_concern_is_acknowledged (bulk->write_concern)); _mongoc_array_append_val (&bulk->commands, command); return true; } bool _mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error) /* OUT */ { mongoc_write_command_t command = {0}; mongoc_write_command_t *last; ENTRY; BULK_RETURN_IF_PRIOR_ERROR; BSON_ASSERT (bulk); BSON_ASSERT (selector); BSON_ASSERT (document); if (!_mongoc_validate_replace (document, error)) { RETURN (false); } if (bulk->commands.len) { last = &_mongoc_array_index ( &bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (SHOULD_APPEND (last, MONGOC_WRITE_COMMAND_UPDATE)) { _mongoc_write_command_update_append (last, selector, document, opts); RETURN (true); } } _mongoc_write_command_init_update ( &command, selector, document, opts, bulk->flags, bulk->operation_id); _mongoc_array_append_val (&bulk->commands, command); RETURN (true); } void mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert) { bson_t opts; bson_error_t *error = &bulk->result.error; ENTRY; bson_init (&opts); BSON_APPEND_BOOL (&opts, "upsert", upsert); BSON_APPEND_BOOL (&opts, "multi", false); _mongoc_bulk_operation_replace_one_with_opts ( bulk, selector, document, &opts, error); bson_destroy (&opts); if (error->domain) { MONGOC_WARNING ("%s", error->message); } EXIT; } bool mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error) /* OUT */ { bson_iter_t iter; bson_t opts_dup; bool retval; ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (selector); BSON_ASSERT (document); if (opts && bson_iter_init_find (&iter, opts, "multi")) { if (!BSON_ITER_HOLDS_BOOL (&iter) || bson_iter_bool (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "%s expects the 'multi' option to be false", BSON_FUNC); RETURN (false); } retval = _mongoc_bulk_operation_replace_one_with_opts ( bulk, selector, document, opts, error); } else { bson_init (&opts_dup); BSON_APPEND_BOOL (&opts_dup, "multi", false); if (opts) { bson_concat (&opts_dup, opts); } retval = _mongoc_bulk_operation_replace_one_with_opts ( bulk, selector, document, &opts_dup, error); bson_destroy (&opts_dup); } RETURN (retval); } bool _mongoc_bulk_operation_update_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error) /* OUT */ { mongoc_write_command_t command = {0}; mongoc_write_command_t *last; ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (selector); BSON_ASSERT (document); BULK_RETURN_IF_PRIOR_ERROR; if (!_mongoc_validate_update (document, error)) { RETURN (false); } if (bulk->commands.len) { last = &_mongoc_array_index ( &bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (SHOULD_APPEND (last, MONGOC_WRITE_COMMAND_UPDATE)) { _mongoc_write_command_update_append (last, selector, document, opts); RETURN (true); } } _mongoc_write_command_init_update ( &command, selector, document, opts, bulk->flags, bulk->operation_id); _mongoc_array_append_val (&bulk->commands, command); RETURN (true); } bool mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error) /* OUT */ { bool retval; bson_t opts_dup; bson_iter_t iter; ENTRY; if (opts && bson_iter_init_find (&iter, opts, "multi")) { if (!BSON_ITER_HOLDS_BOOL (&iter) || bson_iter_bool (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "%s expects the 'multi' option to be false", BSON_FUNC); RETURN (false); } RETURN (_mongoc_bulk_operation_update_with_opts ( bulk, selector, document, opts, error)); } bson_init (&opts_dup); BSON_APPEND_BOOL (&opts_dup, "multi", false); if (opts) { bson_concat (&opts_dup, opts); } retval = _mongoc_bulk_operation_update_with_opts ( bulk, selector, document, &opts_dup, error); bson_destroy (&opts_dup); RETURN (retval); } bool mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error) /* OUT */ { bool retval; bson_t opts_dup; bson_iter_t iter; ENTRY; if (opts && bson_iter_init_find (&iter, opts, "multi")) { if (!BSON_ITER_HOLDS_BOOL (&iter) || !bson_iter_bool (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "%s expects the 'multi' option to be true", BSON_FUNC); RETURN (false); } return _mongoc_bulk_operation_update_with_opts ( bulk, selector, document, opts, error); } bson_init (&opts_dup); BSON_APPEND_BOOL (&opts_dup, "multi", true); if (opts) { bson_concat (&opts_dup, opts); } retval = _mongoc_bulk_operation_update_with_opts ( bulk, selector, document, &opts_dup, error); bson_destroy (&opts_dup); RETURN (retval); } void mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert) { bson_t opts; bson_error_t *error = &bulk->result.error; ENTRY; BULK_EXIT_IF_PRIOR_ERROR; bson_init (&opts); BSON_APPEND_BOOL (&opts, "upsert", upsert); BSON_APPEND_BOOL (&opts, "multi", true); _mongoc_bulk_operation_update_with_opts ( bulk, selector, document, &opts, error); bson_destroy (&opts); if (error->domain) { MONGOC_WARNING ("%s", error->message); } EXIT; } void mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert) { bson_t opts; bson_error_t *error = &bulk->result.error; ENTRY; BULK_EXIT_IF_PRIOR_ERROR; bson_init (&opts); BSON_APPEND_BOOL (&opts, "upsert", upsert); BSON_APPEND_BOOL (&opts, "multi", false); _mongoc_bulk_operation_update_with_opts ( bulk, selector, document, &opts, error); bson_destroy (&opts); if (error->domain) { MONGOC_WARNING ("%s", error->message); } 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); 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); } cluster = &bulk->client->cluster; if (bulk->executed) { _mongoc_write_result_destroy (&bulk->result); } bulk->executed = true; if (reply) { bson_init (reply); } 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); } /* error stored by functions like mongoc_bulk_operation_insert that * can't report errors immediately */ if (bulk->result.error.domain) { if (error) { memcpy (error, &bulk->result.error, sizeof (bson_error_t)); } RETURN (false); } 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->server_id) { server_stream = mongoc_cluster_stream_for_server ( cluster, bulk->server_id, 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->server_id = server_stream->sd->id; if (bulk->result.failed && (bulk->flags.ordered || bulk->result.must_stop)) { GOTO (cleanup); } offset += command->n_documents; } cleanup: ret = _mongoc_write_result_complete (&bulk->result, bulk->client->error_api_version, bulk->write_concern, MONGOC_ERROR_COMMAND /* err domain */, reply, error); mongoc_server_stream_cleanup (server_stream); RETURN (ret ? bulk->server_id : 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; /* if you call set_client, bulk was likely made by mongoc_bulk_operation_new, * not mongoc_collection_create_bulk_operation(), so operation_id is 0. */ if (!bulk->operation_id) { bulk->operation_id = ++bulk->client->cluster.operation_id; } } uint32_t mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk) { BSON_ASSERT (bulk); return bulk->server_id; } void mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk, uint32_t server_id) { BSON_ASSERT (bulk); bulk->server_id = server_id; } 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.3.4/src/libmongoc/src/mongoc/mongoc-bulk-operation.h0000664000175000017500000001443613210321137024202 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-macros.h" #include "mongoc-write-concern.h" #define MONGOC_BULK_WRITE_FLAGS_INIT \ { \ true, MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT, 0 \ } 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; MONGOC_EXPORT (void) mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk); MONGOC_EXPORT (uint32_t) mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (void) mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk, const bson_t *selector) BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove); MONGOC_EXPORT (void) mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk, const bson_t *selector) BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove_one); MONGOC_EXPORT (void) mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk, const bson_t *document); MONGOC_EXPORT (bool) mongoc_bulk_operation_insert_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *document, const bson_t *opts, bson_error_t *error); /* OUT */ MONGOC_EXPORT (void) mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, const bson_t *selector); MONGOC_EXPORT (bool) mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *opts, bson_error_t *error); /* OUT */ MONGOC_EXPORT (void) mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, const bson_t *selector); MONGOC_EXPORT (bool) mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *opts, bson_error_t *error); /* OUT */ MONGOC_EXPORT (void) mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert); MONGOC_EXPORT (bool) mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error); /* OUT */ MONGOC_EXPORT (void) mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert); MONGOC_EXPORT (bool) mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error); /* OUT */ MONGOC_EXPORT (void) mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert); MONGOC_EXPORT (bool) mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, const bson_t *opts, bson_error_t *error); /* OUT */ MONGOC_EXPORT (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_EXPORT (mongoc_bulk_operation_t *) mongoc_bulk_operation_new (bool ordered); MONGOC_EXPORT (void) mongoc_bulk_operation_set_write_concern ( mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (void) mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk, const char *database); MONGOC_EXPORT (void) mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk, const char *collection); MONGOC_EXPORT (void) mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client); /* These names include the term "hint" for backward compatibility, should be * mongoc_bulk_operation_get_server_id, mongoc_bulk_operation_set_server_id. */ MONGOC_EXPORT (void) mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk, uint32_t server_id); MONGOC_EXPORT (uint32_t) mongoc_bulk_operation_get_hint (const mongoc_bulk_operation_t *bulk); MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-client-pool-private.h0000664000175000017500000000260113210321137025133 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_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-client-pool.h" #include "mongoc-topology-description.h" #include "mongoc-topology-private.h" BSON_BEGIN_DECLS /* for tests */ void _mongoc_client_pool_set_stream_initiator (mongoc_client_pool_t *pool, mongoc_stream_initiator_t si, void *user_data); size_t mongoc_client_pool_get_size (mongoc_client_pool_t *pool); size_t mongoc_client_pool_num_pushed (mongoc_client_pool_t *pool); mongoc_topology_t * _mongoc_client_pool_get_topology (mongoc_client_pool_t *pool); BSON_END_DECLS #endif /* MONGOC_CLIENT_POOL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-client-pool.c0000664000175000017500000002420713210321137023464 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.h" #include "mongoc-apm-private.h" #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-private.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-ssl-private.h" #endif 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 bool apm_callbacks_set; mongoc_apm_callbacks_t apm_callbacks; void *apm_context; int32_t error_api_version; bool error_api_set; }; #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); _mongoc_ssl_opts_cleanup (&pool->ssl_opts); memset (&pool->ssl_opts, 0, sizeof pool->ssl_opts); pool->ssl_opts_set = false; if (opts) { _mongoc_ssl_opts_copy_to (opts, &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; const char *appname; 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; pool->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY; b = mongoc_uri_get_options (pool->uri); if (bson_iter_init_find_case (&iter, b, MONGOC_URI_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, MONGOC_URI_MAXPOOLSIZE)) { if (BSON_ITER_HOLDS_INT32 (&iter)) { pool->max_pool_size = BSON_MAX (1, bson_iter_int32 (&iter)); } } appname = mongoc_uri_get_option_as_utf8 (pool->uri, MONGOC_URI_APPNAME, NULL); if (appname) { /* the appname should have already been validated */ BSON_ASSERT (mongoc_client_pool_set_appname (pool, appname)); } #ifdef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (pool->uri)) { mongoc_ssl_opt_t ssl_opt = {0}; _mongoc_ssl_opts_from_uri (&ssl_opt, pool->uri); /* sets use_ssl = true */ mongoc_client_pool_set_ssl_opts (pool, &ssl_opt); } #endif 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); #ifdef MONGOC_ENABLE_SSL _mongoc_ssl_opts_cleanup (&pool->ssl_opts); #endif bson_free (pool); mongoc_counter_client_pools_active_dec (); mongoc_counter_client_pools_disposed_inc (); EXIT; } /* * Start the background topology scanner. * * This function assumes the pool's mutex is locked */ static void _start_scanner_if_needed (mongoc_client_pool_t *pool) { if (!_mongoc_topology_start_background_scanner (pool->topology)) { MONGOC_ERROR ("Background scanner did not start!"); abort (); } } 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); /* for tests */ mongoc_client_set_stream_initiator ( client, pool->topology->scanner->initiator, pool->topology->scanner->initiator_context); client->error_api_version = pool->error_api_version; _mongoc_client_set_apm_callbacks_private ( client, &pool->apm_callbacks, pool->apm_context); #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); } } _start_scanner_if_needed (pool); 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++; } } if (client) { _start_scanner_if_needed (pool); } 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); _mongoc_queue_push_head (&pool->queue, client); if (pool->min_pool_size && _mongoc_queue_get_length (&pool->queue) > pool->min_pool_size) { mongoc_client_t *old_client; old_client = (mongoc_client_t *) _mongoc_queue_pop_tail (&pool->queue); if (old_client) { mongoc_client_destroy (old_client); pool->size--; } } mongoc_cond_signal (&pool->cond); mongoc_mutex_unlock (&pool->mutex); EXIT; } /* for tests */ void _mongoc_client_pool_set_stream_initiator (mongoc_client_pool_t *pool, mongoc_stream_initiator_t si, void *context) { mongoc_topology_scanner_set_stream_initiator ( pool->topology->scanner, si, context); } /* for tests */ 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); } size_t mongoc_client_pool_num_pushed (mongoc_client_pool_t *pool) { size_t num_pushed = 0; ENTRY; mongoc_mutex_lock (&pool->mutex); num_pushed = pool->queue.length; mongoc_mutex_unlock (&pool->mutex); RETURN (num_pushed); } mongoc_topology_t * _mongoc_client_pool_get_topology (mongoc_client_pool_t *pool) { return pool->topology; } 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; } bool mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool, mongoc_apm_callbacks_t *callbacks, void *context) { mongoc_topology_t *topology; topology = pool->topology; if (pool->apm_callbacks_set) { MONGOC_ERROR ("Can only set callbacks once"); return false; } mongoc_mutex_lock (&topology->mutex); if (callbacks) { memcpy (&topology->description.apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); memcpy (&pool->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); } mongoc_topology_set_apm_callbacks (topology, callbacks, context); topology->description.apm_context = context; pool->apm_context = context; pool->apm_callbacks_set = true; mongoc_mutex_unlock (&topology->mutex); return true; } bool mongoc_client_pool_set_error_api (mongoc_client_pool_t *pool, int32_t version) { if (version != MONGOC_ERROR_API_VERSION_LEGACY && version != MONGOC_ERROR_API_VERSION_2) { MONGOC_ERROR ("Unsupported Error API Version: %" PRId32, version); return false; } if (pool->error_api_set) { MONGOC_ERROR ("Can only set Error API Version once"); return false; } pool->error_api_version = version; pool->error_api_set = true; return true; } bool mongoc_client_pool_set_appname (mongoc_client_pool_t *pool, const char *appname) { bool ret; mongoc_mutex_lock (&pool->mutex); ret = _mongoc_topology_set_appname (pool->topology, appname); mongoc_mutex_unlock (&pool->mutex); return ret; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-client-pool.h0000664000175000017500000000462013210321137023466 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-macros.h" #include "mongoc-apm.h" #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_EXPORT (mongoc_client_pool_t *) mongoc_client_pool_new (const mongoc_uri_t *uri); MONGOC_EXPORT (void) mongoc_client_pool_destroy (mongoc_client_pool_t *pool); MONGOC_EXPORT (mongoc_client_t *) mongoc_client_pool_pop (mongoc_client_pool_t *pool); MONGOC_EXPORT (void) mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client); MONGOC_EXPORT (mongoc_client_t *) mongoc_client_pool_try_pop (mongoc_client_pool_t *pool); MONGOC_EXPORT (void) mongoc_client_pool_max_size (mongoc_client_pool_t *pool, uint32_t max_pool_size); MONGOC_EXPORT (void) mongoc_client_pool_min_size (mongoc_client_pool_t *pool, uint32_t min_pool_size); #ifdef MONGOC_ENABLE_SSL MONGOC_EXPORT (void) mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool, const mongoc_ssl_opt_t *opts); #endif MONGOC_EXPORT (bool) mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool, mongoc_apm_callbacks_t *callbacks, void *context); MONGOC_EXPORT (bool) mongoc_client_pool_set_error_api (mongoc_client_pool_t *pool, int32_t version); MONGOC_EXPORT (bool) mongoc_client_pool_set_appname (mongoc_client_pool_t *pool, const char *appname); BSON_END_DECLS #endif /* MONGOC_CLIENT_POOL_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-client-private.h0000664000175000017500000001253113210321137024167 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_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-apm-private.h" #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 5 /* 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 /* first version to support maxStalenessSeconds */ #define WIRE_VERSION_MAX_STALENESS 5 /* first version to support writeConcern */ #define WIRE_VERSION_CMD_WRITE_CONCERN 5 /* first version to support collation */ #define WIRE_VERSION_COLLATION 5 struct _mongoc_client_t { 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; #endif mongoc_topology_t *topology; mongoc_read_prefs_t *read_prefs; mongoc_read_concern_t *read_concern; mongoc_write_concern_t *write_concern; mongoc_apm_callbacks_t apm_callbacks; void *apm_context; int32_t error_api_version; bool error_api_set; }; /* Defines whether _mongoc_client_command_with_opts() is acting as a read * command helper for a command like "distinct", or a write command helper for * a command like "createRole", or both, like "aggregate" with "$out". */ typedef enum { MONGOC_CMD_READ = 1, MONGOC_CMD_WRITE = 2, MONGOC_CMD_RW = 3, } mongoc_command_mode_t; BSON_STATIC_ASSERT (MONGOC_CMD_RW == (MONGOC_CMD_READ | MONGOC_CMD_WRITE)); mongoc_client_t * _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topology); bool _mongoc_client_set_apm_callbacks_private (mongoc_client_t *client, mongoc_apm_callbacks_t *callbacks, void *context); 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_client_kill_cursor (mongoc_client_t *client, uint32_t server_id, int64_t cursor_id, int64_t operation_id, const char *db, const char *collection); bool _mongoc_client_command_with_opts (mongoc_client_t *client, const char *db_name, const bson_t *command, mongoc_command_mode_t mode, const bson_t *opts, mongoc_query_flags_t flags, const mongoc_read_prefs_t *default_prefs, mongoc_read_concern_t *default_rc, mongoc_write_concern_t *default_wc, bson_t *reply, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_CLIENT_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-client.c0000664000175000017500000016445213210321137022524 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-private.h" #include "mongoc-uri-private.h" #include "mongoc-util-private.h" #include "mongoc-set-private.h" #include "mongoc-log.h" #include "mongoc-write-concern-private.h" #include "mongoc-read-concern-private.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-stream-tls.h" #include "mongoc-ssl-private.h" #include "mongoc-cmd-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, int64_t operation_id, const char *db, const char *collection); 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, MONGOC_URI_CONNECTTIMEOUTMS, MONGOC_DEFAULT_CONNECTTIMEOUTMS); BSON_ASSERT (connecttimeoutms); 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. */ expire_at = bson_get_monotonic_time () + (connecttimeoutms * 1000L); if (0 != mongoc_socket_connect ( sock, rp->ai_addr, (mongoc_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) { case AF_UNSPEC: #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")))) { mongoc_stream_t *original = base_stream; base_stream = mongoc_stream_tls_new_with_hostname ( base_stream, host->host, &client->ssl_opts, true); if (!base_stream) { mongoc_stream_destroy (original); 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, MONGOC_URI_CONNECTTIMEOUTMS, MONGOC_DEFAULT_CONNECTTIMEOUTMS); if (!mongoc_stream_tls_handshake_block ( base_stream, host->host, connecttimeoutms, error)) { 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, error); 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, int32_t error_api_version, bson_error_t *error) { bson_iter_t iter; uint32_t code = 0; mongoc_error_domain_t domain = error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER : MONGOC_ERROR_QUERY; BSON_ASSERT (b); if (!error) { return; } if (bson_iter_init_find (&iter, b, "code") && BSON_ITER_HOLDS_INT32 (&iter)) { code = (uint32_t) bson_iter_int32 (&iter); } if (bson_iter_init_find (&iter, b, "$err") && BSON_ITER_HOLDS_UTF8 (&iter)) { bson_set_error (error, domain, 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, domain, code, "%s", bson_iter_utf8 (&iter, NULL)); return; } bson_set_error (error, MONGOC_ERROR_QUERY, MONGOC_ERROR_QUERY_FAILURE, "An unknown error occurred 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, error); 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, client->error_api_version, 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, client->error_api_version, 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); if (!client) { mongoc_topology_destroy (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); _mongoc_ssl_opts_cleanup (&client->ssl_opts); client->use_ssl = true; _mongoc_ssl_opts_copy_to (opts, &client->ssl_opts); 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; const char *appname; 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->initiator = mongoc_client_default_stream_initiator; client->initiator_data = client; client->topology = topology; client->error_api_version = MONGOC_ERROR_API_VERSION_LEGACY; client->error_api_set = false; 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); appname = mongoc_uri_get_option_as_utf8 (client->uri, MONGOC_URI_APPNAME, NULL); if (appname && client->topology->single_threaded) { /* the appname should have already been validated */ BSON_ASSERT (mongoc_client_set_appname (client, appname)); } mongoc_cluster_init (&client->cluster, client->uri, client); #ifdef MONGOC_ENABLE_SSL client->use_ssl = false; if (mongoc_uri_get_ssl (client->uri)) { mongoc_ssl_opt_t ssl_opt = {0}; _mongoc_ssl_opts_from_uri (&ssl_opt, client->uri); /* sets use_ssl = true */ mongoc_client_set_ssl_opts (client, &ssl_opt); } #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) { 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); #ifdef MONGOC_ENABLE_SSL _mongoc_ssl_opts_cleanup (&client->ssl_opts); #endif 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]; mongoc_cursor_t *cursor; BSON_ASSERT (client); BSON_ASSERT (db_name); BSON_ASSERT (query); /* * 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; } /* flags, skip, limit, batch_size, fields are unused */ cursor = _mongoc_cursor_new_with_opts ( client, db_name, true /* is_command */, query, NULL, read_prefs, NULL); return cursor; } static bool _mongoc_client_command_with_stream (mongoc_client_t *client, mongoc_cmd_parts_t *parts, mongoc_server_stream_t *server_stream, bson_t *reply, bson_error_t *error) { ENTRY; parts->assembled.operation_id = ++client->cluster.operation_id; RETURN (mongoc_cluster_run_command_monitored ( &client->cluster, parts, server_stream, reply, error)); } 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 = NULL; mongoc_cmd_parts_t parts; bool ret; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db_name); BSON_ASSERT (command); if (!_mongoc_read_prefs_validate (read_prefs, error)) { RETURN (false); } cluster = &client->cluster; mongoc_cmd_parts_init (&parts, db_name, MONGOC_QUERY_NONE, command); parts.read_prefs = read_prefs; /* Server Selection Spec: "The generic command method has a default read * preference of mode 'primary'. The generic command method MUST ignore any * default read preference from client, database or collection * configuration. The generic command method SHOULD allow an optional read * preference argument." */ server_stream = mongoc_cluster_stream_for_reads (cluster, read_prefs, error); if (server_stream) { ret = _mongoc_client_command_with_stream ( client, &parts, server_stream, reply, error); } else { if (reply) { bson_init (reply); } ret = false; } mongoc_cmd_parts_cleanup (&parts); mongoc_server_stream_cleanup (server_stream); RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_client_command_with_opts -- * * Execute a command on the server. If mode is MONGOC_CMD_READ or * MONGOC_CMD_RW, then read concern is applied from @opts, or else from * @default_rc, and read preferences are applied from @default_prefs. * If mode is MONGOC_CMD_WRITE or MONGOC_CMD_RW, then write concern is * applied from @opts if present, or else from @default_wc. * * The mongoc_client_t's read preference, read concern, and write concern * are *NOT* applied. * * Returns: * Success or failure. * A write concern timeout or write concern error is considered a failure. * * Side effects: * @reply is always initialized. * @error is filled out if the command fails. * *-------------------------------------------------------------------------- */ bool _mongoc_client_command_with_opts (mongoc_client_t *client, const char *db_name, const bson_t *command, mongoc_command_mode_t mode, const bson_t *opts, mongoc_query_flags_t flags, const mongoc_read_prefs_t *default_prefs, mongoc_read_concern_t *default_rc, mongoc_write_concern_t *default_wc, bson_t *reply, bson_error_t *error) { mongoc_cmd_parts_t parts; mongoc_server_stream_t *server_stream = NULL; mongoc_cluster_t *cluster; bson_t reply_local; bson_t *reply_ptr; uint32_t server_id; bool ret = false; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db_name); BSON_ASSERT (command); mongoc_cmd_parts_init (&parts, db_name, flags, command); parts.is_write_command = (mode & MONGOC_CMD_WRITE); reply_ptr = reply ? reply : &reply_local; if (mode == MONGOC_CMD_READ) { /* NULL read pref is ok */ if (!_mongoc_read_prefs_validate (default_prefs, error)) { GOTO (err); } parts.read_prefs = default_prefs; } else { /* this is a command that writes */ default_prefs = NULL; } cluster = &client->cluster; if (!_mongoc_get_server_id_from_opts (opts, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, &server_id, error)) { GOTO (err); } if (server_id) { /* "serverId" passed in opts */ server_stream = mongoc_cluster_stream_for_server ( cluster, server_id, true /* reconnect ok */, error); if (server_stream && server_stream->sd->type != MONGOC_SERVER_MONGOS) { parts.user_query_flags |= MONGOC_QUERY_SLAVE_OK; } } else if (parts.is_write_command) { server_stream = mongoc_cluster_stream_for_writes (cluster, error); } else { server_stream = mongoc_cluster_stream_for_reads (cluster, default_prefs, error); } if (server_stream) { bson_iter_t iter; if (opts && bson_iter_init (&iter, opts)) { if (!mongoc_cmd_parts_append_opts (&parts, &iter, server_stream->sd->max_wire_version, error)) { GOTO (err); } } /* use default write concern unless it's in opts */ if ((mode & MONGOC_CMD_WRITE) && server_stream->sd->max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN && !mongoc_write_concern_is_default (default_wc) && (!opts || !bson_has_field (opts, "writeConcern"))) { bson_append_document (&parts.extra, "writeConcern", 12, _mongoc_write_concern_get_bson (default_wc)); } /* use read prefs and read concern for read commands, unless in opts */ if ((mode & MONGOC_CMD_READ) && server_stream->sd->max_wire_version >= WIRE_VERSION_READ_CONCERN && !mongoc_read_concern_is_default (default_rc) && (!opts || !bson_has_field (opts, "readConcern"))) { bson_append_document (&parts.extra, "readConcern", 11, _mongoc_read_concern_get_bson (default_rc)); } ret = _mongoc_client_command_with_stream ( client, &parts, server_stream, reply_ptr, error); if (ret && (mode & MONGOC_CMD_WRITE)) { ret = !_mongoc_parse_wc_err (reply_ptr, error); } if (reply_ptr == &reply_local) { bson_destroy (reply_ptr); } GOTO (done); } err: if (reply) { bson_init (reply); } done: if (server_stream) { mongoc_server_stream_cleanup (server_stream); } mongoc_cmd_parts_cleanup (&parts); RETURN (ret); } bool mongoc_client_read_command_with_opts (mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs, const bson_t *opts, bson_t *reply, bson_error_t *error) { return _mongoc_client_command_with_opts ( client, db_name, command, MONGOC_CMD_READ, opts, MONGOC_QUERY_NONE, COALESCE (read_prefs, client->read_prefs), client->read_concern, client->write_concern, reply, error); } bool mongoc_client_write_command_with_opts (mongoc_client_t *client, const char *db_name, const bson_t *command, const bson_t *opts, bson_t *reply, bson_error_t *error) { return _mongoc_client_command_with_opts (client, db_name, command, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, client->read_prefs, client->read_concern, client->write_concern, reply, error); } bool mongoc_client_read_write_command_with_opts ( mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs /* IGNORED */, const bson_t *opts, bson_t *reply, bson_error_t *error) { return _mongoc_client_command_with_opts ( client, db_name, command, MONGOC_CMD_RW, opts, MONGOC_QUERY_NONE, COALESCE (read_prefs, client->read_prefs), client->read_concern, client->write_concern, reply, error); } bool mongoc_client_command_simple_with_server_id ( mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs, uint32_t server_id, bson_t *reply, bson_error_t *error) { mongoc_server_stream_t *server_stream; mongoc_cmd_parts_t parts; bool ret; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db_name); BSON_ASSERT (command); if (!_mongoc_read_prefs_validate (read_prefs, error)) { RETURN (false); } mongoc_cmd_parts_init (&parts, db_name, MONGOC_QUERY_NONE, command); parts.read_prefs = read_prefs; server_stream = mongoc_cluster_stream_for_server ( &client->cluster, server_id, true /* reconnect ok */, error); if (server_stream) { ret = _mongoc_client_command_with_stream ( client, &parts, server_stream, reply, error); mongoc_server_stream_cleanup (server_stream); RETURN (ret); } else { if (reply) { bson_init (reply); } RETURN (false); } } static void _mongoc_client_prepare_killcursors_command (int64_t cursor_id, const char *collection, bson_t *command) { 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); } void _mongoc_client_kill_cursor (mongoc_client_t *client, uint32_t server_id, int64_t cursor_id, int64_t operation_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, operation_id, db, collection); } mongoc_server_stream_cleanup (server_stream); EXIT; } static void _mongoc_client_monitor_op_killcursors (mongoc_cluster_t *cluster, mongoc_server_stream_t *server_stream, int64_t cursor_id, int64_t operation_id, const char *db, const char *collection) { bson_t doc; mongoc_client_t *client; mongoc_apm_command_started_t event; ENTRY; client = cluster->client; if (!client->apm_callbacks.started) { return; } bson_init (&doc); _mongoc_client_prepare_killcursors_command (cursor_id, collection, &doc); mongoc_apm_command_started_init (&event, &doc, db, "killCursors", cluster->request_id, operation_id, &server_stream->sd->host, server_stream->sd->id, client->apm_context); client->apm_callbacks.started (&event); mongoc_apm_command_started_cleanup (&event); bson_destroy (&doc); EXIT; } static void _mongoc_client_monitor_op_killcursors_succeeded ( mongoc_cluster_t *cluster, int64_t duration, mongoc_server_stream_t *server_stream, int64_t cursor_id, int64_t operation_id) { mongoc_client_t *client; bson_t doc; bson_t cursors_unknown; mongoc_apm_command_succeeded_t event; ENTRY; client = cluster->client; if (!client->apm_callbacks.succeeded) { EXIT; } /* fake server reply to killCursors command: {ok: 1, cursorsUnknown: [42]} */ bson_init (&doc); bson_append_int32 (&doc, "ok", 2, 1); bson_append_array_begin (&doc, "cursorsUnknown", 14, &cursors_unknown); bson_append_int64 (&cursors_unknown, "0", 1, cursor_id); bson_append_array_end (&doc, &cursors_unknown); mongoc_apm_command_succeeded_init (&event, duration, &doc, "killCursors", cluster->request_id, operation_id, &server_stream->sd->host, server_stream->sd->id, client->apm_context); client->apm_callbacks.succeeded (&event); mongoc_apm_command_succeeded_cleanup (&event); bson_destroy (&doc); } static void _mongoc_client_monitor_op_killcursors_failed ( mongoc_cluster_t *cluster, int64_t duration, mongoc_server_stream_t *server_stream, const bson_error_t *error, int64_t operation_id) { mongoc_client_t *client; mongoc_apm_command_failed_t event; ENTRY; client = cluster->client; if (!client->apm_callbacks.failed) { EXIT; } mongoc_apm_command_failed_init (&event, duration, "killCursors", error, cluster->request_id, operation_id, &server_stream->sd->host, server_stream->sd->id, client->apm_context); client->apm_callbacks.failed (&event); mongoc_apm_command_failed_cleanup (&event); } static void _mongoc_client_op_killcursors (mongoc_cluster_t *cluster, mongoc_server_stream_t *server_stream, int64_t cursor_id, int64_t operation_id, const char *db, const char *collection) { int64_t started; mongoc_rpc_t rpc = {{0}}; bson_error_t error; bool has_ns; bool r; /* called by old mongoc_client_kill_cursor without db/collection? */ has_ns = (db && collection); started = bson_get_monotonic_time (); ++cluster->request_id; rpc.header.msg_len = 0; rpc.header.request_id = cluster->request_id; rpc.header.response_to = 0; rpc.header.opcode = MONGOC_OPCODE_KILL_CURSORS; rpc.kill_cursors.zero = 0; rpc.kill_cursors.cursors = &cursor_id; rpc.kill_cursors.n_cursors = 1; if (has_ns) { _mongoc_client_monitor_op_killcursors ( cluster, server_stream, cursor_id, operation_id, db, collection); } r = mongoc_cluster_sendv_to_server ( cluster, &rpc, server_stream, NULL, &error); if (has_ns) { if (r) { _mongoc_client_monitor_op_killcursors_succeeded ( cluster, bson_get_monotonic_time () - started, server_stream, cursor_id, operation_id); } else { _mongoc_client_monitor_op_killcursors_failed ( cluster, bson_get_monotonic_time () - started, server_stream, &error, operation_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) { bson_t command = BSON_INITIALIZER; mongoc_cmd_parts_t parts; ENTRY; _mongoc_client_prepare_killcursors_command (cursor_id, collection, &command); mongoc_cmd_parts_init (&parts, db, MONGOC_QUERY_SLAVE_OK, &command); parts.assembled.operation_id = ++cluster->operation_id; /* Find, getMore And killCursors Commands Spec: "The result from the * killCursors command MAY be safely ignored." */ mongoc_cluster_run_command_monitored ( cluster, &parts, server_stream, NULL, NULL); mongoc_cmd_parts_cleanup (&parts); bson_destroy (&command); EXIT; } /* *-------------------------------------------------------------------------- * * 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; bson_error_t error; uint32_t server_id = 0; topology = client->topology; read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); mongoc_mutex_lock (&topology->mutex); if (!mongoc_topology_compatible (&topology->description, NULL, &error)) { MONGOC_ERROR ("Could not kill cursor: %s", error.message); mongoc_mutex_unlock (&topology->mutex); mongoc_read_prefs_destroy (read_prefs); return; } /* 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, topology->local_threshold_msec); if (selected_server) { server_id = selected_server->id; } mongoc_mutex_unlock (&topology->mutex); if (server_id) { _mongoc_client_kill_cursor (client, server_id, cursor_id, 0 /* operation_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))) { 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); /* ignore client read prefs */ cursor = _mongoc_cursor_new_with_opts ( client, "admin", true /* is_command */, 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); } } bool _mongoc_client_set_apm_callbacks_private (mongoc_client_t *client, mongoc_apm_callbacks_t *callbacks, void *context) { if (callbacks) { memcpy ( &client->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); } else { memset (&client->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t)); } client->apm_context = context; mongoc_topology_set_apm_callbacks (client->topology, callbacks, context); return true; } bool mongoc_client_set_apm_callbacks (mongoc_client_t *client, mongoc_apm_callbacks_t *callbacks, void *context) { if (!client->topology->single_threaded) { MONGOC_ERROR ("Cannot set callbacks on a pooled client, use " "mongoc_client_pool_set_apm_callbacks"); return false; } return _mongoc_client_set_apm_callbacks_private (client, callbacks, context); } mongoc_server_description_t * mongoc_client_get_server_description (mongoc_client_t *client, uint32_t server_id) { /* the error info isn't useful */ return mongoc_topology_server_by_id (client->topology, server_id, NULL); } mongoc_server_description_t ** mongoc_client_get_server_descriptions (const mongoc_client_t *client, size_t *n /* OUT */) { mongoc_topology_t *topology; mongoc_server_description_t **sds; BSON_ASSERT (client); BSON_ASSERT (n); topology = client->topology; /* in case the client is pooled */ mongoc_mutex_lock (&topology->mutex); sds = mongoc_topology_description_get_servers (&topology->description, n); mongoc_mutex_unlock (&topology->mutex); return sds; } void mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds, size_t n) { size_t i; for (i = 0; i < n; ++i) { mongoc_server_description_destroy (sds[i]); } bson_free (sds); } mongoc_server_description_t * mongoc_client_select_server (mongoc_client_t *client, bool for_writes, const mongoc_read_prefs_t *prefs, bson_error_t *error) { mongoc_ss_optype_t optype = for_writes ? MONGOC_SS_WRITE : MONGOC_SS_READ; mongoc_server_description_t *sd; if (for_writes && prefs) { bson_set_error (error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "Cannot use read preferences with for_writes = true"); return NULL; } if (!_mongoc_read_prefs_validate (prefs, error)) { return NULL; } sd = mongoc_topology_select (client->topology, optype, prefs, error); if (!sd) { return NULL; } if (mongoc_cluster_check_interval (&client->cluster, sd->id)) { /* check not required, or it succeeded */ return sd; } /* check failed, retry once */ mongoc_server_description_destroy (sd); sd = mongoc_topology_select (client->topology, optype, prefs, error); if (sd) { return sd; } return NULL; } bool mongoc_client_set_error_api (mongoc_client_t *client, int32_t version) { if (!client->topology->single_threaded) { MONGOC_ERROR ("Cannot set Error API Version on a pooled client, use " "mongoc_client_pool_set_error_api"); return false; } if (version != MONGOC_ERROR_API_VERSION_LEGACY && version != MONGOC_ERROR_API_VERSION_2) { MONGOC_ERROR ("Unsupported Error API Version: %" PRId32, version); return false; } if (client->error_api_set) { MONGOC_ERROR ("Can only set Error API Version once"); return false; } client->error_api_version = version; client->error_api_set = true; return true; } bool mongoc_client_set_appname (mongoc_client_t *client, const char *appname) { if (!client->topology->single_threaded) { MONGOC_ERROR ("Cannot call set_appname on a client from a pool"); return false; } return _mongoc_topology_set_appname (client->topology, appname); } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-client.h0000664000175000017500000002147713210321137022530 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-macros.h" #include "mongoc-apm.h" #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" #include "mongoc-server-description.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_EXPORT (mongoc_client_t *) mongoc_client_new (const char *uri_string); MONGOC_EXPORT (mongoc_client_t *) mongoc_client_new_from_uri (const mongoc_uri_t *uri); MONGOC_EXPORT (const mongoc_uri_t *) mongoc_client_get_uri (const mongoc_client_t *client); MONGOC_EXPORT (void) mongoc_client_set_stream_initiator (mongoc_client_t *client, mongoc_stream_initiator_t initiator, void *user_data); MONGOC_EXPORT (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); MONGOC_EXPORT (void) mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (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_EXPORT (bool) mongoc_client_read_command_with_opts (mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_client_write_command_with_opts (mongoc_client_t *client, const char *db_name, const bson_t *command, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_client_read_write_command_with_opts ( mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs /* IGNORED */, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_client_command_simple_with_server_id ( mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs, uint32_t server_id, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (void) mongoc_client_destroy (mongoc_client_t *client); MONGOC_EXPORT (mongoc_database_t *) mongoc_client_get_database (mongoc_client_t *client, const char *name); MONGOC_EXPORT (mongoc_database_t *) mongoc_client_get_default_database (mongoc_client_t *client); MONGOC_EXPORT (mongoc_gridfs_t *) mongoc_client_get_gridfs (mongoc_client_t *client, const char *db, const char *prefix, bson_error_t *error); MONGOC_EXPORT (mongoc_collection_t *) mongoc_client_get_collection (mongoc_client_t *client, const char *db, const char *collection); MONGOC_EXPORT (char **) mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error); MONGOC_EXPORT (mongoc_cursor_t *) mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_client_get_server_status (mongoc_client_t *client, mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (int32_t) mongoc_client_get_max_message_size (mongoc_client_t *client) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (int32_t) mongoc_client_get_max_bson_size (mongoc_client_t *client) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (const mongoc_write_concern_t *) mongoc_client_get_write_concern (const mongoc_client_t *client); MONGOC_EXPORT (void) mongoc_client_set_write_concern (mongoc_client_t *client, const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (const mongoc_read_concern_t *) mongoc_client_get_read_concern (const mongoc_client_t *client); MONGOC_EXPORT (void) mongoc_client_set_read_concern (mongoc_client_t *client, const mongoc_read_concern_t *read_concern); MONGOC_EXPORT (const mongoc_read_prefs_t *) mongoc_client_get_read_prefs (const mongoc_client_t *client); MONGOC_EXPORT (void) mongoc_client_set_read_prefs (mongoc_client_t *client, const mongoc_read_prefs_t *read_prefs); #ifdef MONGOC_ENABLE_SSL MONGOC_EXPORT (void) mongoc_client_set_ssl_opts (mongoc_client_t *client, const mongoc_ssl_opt_t *opts); #endif MONGOC_EXPORT (bool) mongoc_client_set_apm_callbacks (mongoc_client_t *client, mongoc_apm_callbacks_t *callbacks, void *context); MONGOC_EXPORT (mongoc_server_description_t *) mongoc_client_get_server_description (mongoc_client_t *client, uint32_t server_id); MONGOC_EXPORT (mongoc_server_description_t **) mongoc_client_get_server_descriptions (const mongoc_client_t *client, size_t *n); MONGOC_EXPORT (void) mongoc_server_descriptions_destroy_all (mongoc_server_description_t **sds, size_t n); MONGOC_EXPORT (mongoc_server_description_t *) mongoc_client_select_server (mongoc_client_t *client, bool for_writes, const mongoc_read_prefs_t *prefs, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_client_set_error_api (mongoc_client_t *client, int32_t version); MONGOC_EXPORT (bool) mongoc_client_set_appname (mongoc_client_t *client, const char *appname); BSON_END_DECLS #endif /* MONGOC_CLIENT_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-cyrus-private.h0000664000175000017500000000214613210321137025536 0ustar jmikolajmikola/* * Copyright 2017 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_CYRUS_PRIVATE_H #define MONGOC_CLUSTER_CYRUS_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-config.h" #include "mongoc-cluster-private.h" #include bool _mongoc_cluster_auth_node_cyrus (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error); #endif /* MONGOC_CLUSTER_CYRUS_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-cyrus.c0000664000175000017500000000675413210321137024072 0ustar jmikolajmikola/* * Copyright 2017 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_CYRUS #include "mongoc-cyrus-private.h" #include "mongoc-cluster-cyrus-private.h" #include "mongoc-error.h" #include "mongoc-trace-private.h" bool _mongoc_cluster_auth_node_cyrus (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error) { mongoc_cmd_parts_t parts; uint32_t buflen = 0; mongoc_cyrus_t sasl; bson_iter_t iter; bool ret = false; const char *tmpstr; uint8_t buf[4096] = {0}; bson_t cmd; bson_t reply; int conv_id = 0; BSON_ASSERT (cluster); BSON_ASSERT (stream); if (!_mongoc_cyrus_new_from_cluster ( &sasl, cluster, stream, hostname, error)) { return false; } for (;;) { mongoc_cmd_parts_init (&parts, "$external", MONGOC_QUERY_SLAVE_OK, &cmd); if (!_mongoc_cyrus_step ( &sasl, buf, buflen, buf, sizeof buf, &buflen, error)) { goto failure; } bson_init (&cmd); if (sasl.step == 1) { _mongoc_cluster_build_sasl_start ( &cmd, sasl.credentials.mechanism, (const char *) buf, buflen); } else { _mongoc_cluster_build_sasl_continue ( &cmd, conv_id, (const char *) buf, buflen); } TRACE ("SASL: authenticating (step %d)", sasl.step); if (!mongoc_cluster_run_command_private ( cluster, &parts, stream, 0, &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); mongoc_cmd_parts_cleanup (&parts); break; } conv_id = _mongoc_cluster_get_conversation_id (&reply); if (!bson_iter_init_find (&iter, &reply, "payload") || !BSON_ITER_HOLDS_UTF8 (&iter)) { MONGOC_DEBUG ("SASL: authentication failed"); 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_cmd_parts_cleanup (&parts); } TRACE ("%s", "SASL: authenticated"); ret = true; failure: _mongoc_cyrus_destroy (&sasl); mongoc_cmd_parts_cleanup (&parts); return ret; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-gssapi-private.h0000664000175000017500000000215513210321137025657 0ustar jmikolajmikola/* * Copyright 2017 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_GSSAPI_PRIVATE_H #define MONGOC_CLUSTER_GSSAPI_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-config.h" #include "mongoc-cluster-private.h" #include bool _mongoc_cluster_auth_node_gssapi (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error); #endif /* MONGOC_CLUSTER_GSSAPI_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-gssapi.c0000664000175000017500000000273713210321137024210 0ustar jmikolajmikola/* * Copyright 2017 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_GSSAPI #include "mongoc-cluster-gssapi-private.h" #include "mongoc-cluster-sasl-private.h" #include "mongoc-gssapi-private.h" #include "mongoc-error.h" #include "mongoc-util-private.h" /* *-------------------------------------------------------------------------- * * _mongoc_cluster_auth_node_gssapi -- * * Perform authentication for a cluster node using GSSAPI * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * error may be set. * *-------------------------------------------------------------------------- */ bool _mongoc_cluster_auth_node_gssapi (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error) { return false; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-private.h0000664000175000017500000001251413210321137024373 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_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" #include "mongoc-scram-private.h" #include "mongoc-cmd-private.h" BSON_BEGIN_DECLS typedef struct _mongoc_cluster_node_t { mongoc_stream_t *stream; char *connection_address; 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 { int64_t operation_id; uint32_t request_id; uint32_t sockettimeoutms; uint8_t scram_client_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t scram_server_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t scram_salted_password[MONGOC_SCRAM_HASH_SIZE]; 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, bool invalidate, const bson_error_t *why); 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); size_t _mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov, size_t iovcnt, int skip, char *buffer); bool mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id); bool mongoc_cluster_sendv_to_server (mongoc_cluster_t *cluster, mongoc_rpc_t *rpcs, 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_monitored (mongoc_cluster_t *cluster, mongoc_cmd_parts_t *parts, mongoc_server_stream_t *server_stream, bson_t *reply, bson_error_t *error); bool mongoc_cluster_run_command_private (mongoc_cluster_t *cluster, mongoc_cmd_parts_t *parts, mongoc_stream_t *stream, uint32_t server_id, bson_t *reply, bson_error_t *error); void _mongoc_cluster_build_sasl_start (bson_t *cmd, const char *mechanism, const char *buf, uint32_t buflen); void _mongoc_cluster_build_sasl_continue (bson_t *cmd, int conv_id, const char *buf, uint32_t buflen); int _mongoc_cluster_get_conversation_id (const bson_t *reply); BSON_END_DECLS #endif /* MONGOC_CLUSTER_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-sasl-private.h0000664000175000017500000000213713210321137025333 0ustar jmikolajmikola/* * Copyright 2017 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_SASL_PRIVATE_H #define MONGOC_CLUSTER_SASL_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-config.h" #include "mongoc-cluster-private.h" #include bool _mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error); #endif /* MONGOC_CLUSTER_SASL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-sasl.c0000664000175000017500000000623613210321137023662 0ustar jmikolajmikola/* * Copyright 2017 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. */ /* for size_t */ #include #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SASL #include "mongoc-cluster-private.h" #include "mongoc-log.h" #include "mongoc-trace-private.h" #include "mongoc-stream-private.h" #include "mongoc-stream-socket.h" #include "mongoc-error.h" #include "mongoc-util-private.h" #ifdef MONGOC_ENABLE_SASL_CYRUS #include "mongoc-cluster-cyrus-private.h" #endif #ifdef MONGOC_ENABLE_SASL_SSPI #include "mongoc-cluster-sspi-private.h" #endif #ifdef MONGOC_ENABLE_SASL_GSSAPI #include "mongoc-cluster-gssapi-private.h" #endif void _mongoc_cluster_build_sasl_start (bson_t *cmd, const char *mechanism, const char *buf, uint32_t buflen) { BSON_APPEND_INT32 (cmd, "saslStart", 1); BSON_APPEND_UTF8 (cmd, "mechanism", "GSSAPI"); bson_append_utf8 (cmd, "payload", 7, buf, buflen); BSON_APPEND_INT32 (cmd, "autoAuthorize", 1); } void _mongoc_cluster_build_sasl_continue (bson_t *cmd, int conv_id, const char *buf, uint32_t buflen) { BSON_APPEND_INT32 (cmd, "saslContinue", 1); BSON_APPEND_INT32 (cmd, "conversationId", conv_id); bson_append_utf8 (cmd, "payload", 7, buf, buflen); } int _mongoc_cluster_get_conversation_id (const bson_t *reply) { bson_iter_t iter; if (bson_iter_init_find (&iter, reply, "conversationId") && BSON_ITER_HOLDS_INT32 (&iter)) { return bson_iter_int32 (&iter); } return 0; } /* *-------------------------------------------------------------------------- * * _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. * *-------------------------------------------------------------------------- */ bool _mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error) { #ifdef MONGOC_ENABLE_SASL_CYRUS return _mongoc_cluster_auth_node_cyrus (cluster, stream, hostname, error); #endif #ifdef MONGOC_ENABLE_SASL_SSPI return _mongoc_cluster_auth_node_sspi (cluster, stream, hostname, error); #endif #ifdef MONGOC_ENABLE_SASL_GSSAPI return _mongoc_cluster_auth_node_gssapi (cluster, stream, hostname, error); #endif } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-sspi-private.h0000664000175000017500000000213713210321137025347 0ustar jmikolajmikola/* * Copyright 2017 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_SSPI_PRIVATE_H #define MONGOC_CLUSTER_SSPI_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-config.h" #include "mongoc-cluster-private.h" #include bool _mongoc_cluster_auth_node_sspi (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error); #endif /* MONGOC_CLUSTER_SSPI_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster-sspi.c0000664000175000017500000002126313210321137023673 0ustar jmikolajmikola/* * Copyright 2017 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_SSPI #include "mongoc-cluster-sspi-private.h" #include "mongoc-cluster-sasl-private.h" #include "mongoc-sasl-private.h" #include "mongoc-sspi-private.h" #include "mongoc-error.h" #include "mongoc-util-private.h" mongoc_sspi_client_state_t * _mongoc_cluster_sspi_new (mongoc_uri_t *uri, const char *hostname) { WCHAR *service; /* L"serviceName@hostname@REALM" */ const char *service_name = "mongodb"; ULONG flags = ISC_REQ_MUTUAL_AUTH; const char *service_realm = NULL; char *service_ascii = NULL; mongoc_sspi_client_state_t *state; const char *tmp_creds; int service_ascii_len; const bson_t *options; int tmp_creds_len; bson_t properties; bson_iter_t iter; int service_len; int user_len = 0; int pass_len = 0; WCHAR *pass = NULL; WCHAR *user = NULL; int res; options = mongoc_uri_get_options (uri); if (!mongoc_uri_get_mechanism_properties (uri, &properties)) { bson_init (&properties); } if (bson_iter_init_find_case ( &iter, options, MONGOC_URI_GSSAPISERVICENAME) && BSON_ITER_HOLDS_UTF8 (&iter)) { service_name = bson_iter_utf8 (&iter, NULL); } if (bson_iter_init_find_case (&iter, &properties, "SERVICE_NAME") && BSON_ITER_HOLDS_UTF8 (&iter)) { service_name = bson_iter_utf8 (&iter, NULL); } if (bson_iter_init_find_case (&iter, &properties, "SERVICE_REALM") && BSON_ITER_HOLDS_UTF8 (&iter)) { service_realm = bson_iter_utf8 (&iter, NULL); service_ascii = bson_strdup_printf ("%s@%s@%s", service_name, hostname, service_realm); } else { service_ascii = bson_strdup_printf ("%s@%s", service_name, hostname); } service_ascii_len = strlen (service_ascii); /* this is donated to the sspi */ service = calloc (service_ascii_len + 1, sizeof (WCHAR)); service_len = MultiByteToWideChar ( CP_UTF8, 0, service_ascii, service_ascii_len, service, service_ascii_len); service[service_len] = L'\0'; bson_free (service_ascii); tmp_creds = mongoc_uri_get_password (uri); if (tmp_creds) { tmp_creds_len = strlen (tmp_creds); /* this is donated to the sspi */ pass = calloc (tmp_creds_len + 1, sizeof (WCHAR)); pass_len = MultiByteToWideChar ( CP_UTF8, 0, tmp_creds, tmp_creds_len, pass, tmp_creds_len); pass[pass_len] = L'\0'; } tmp_creds = mongoc_uri_get_username (uri); if (tmp_creds) { tmp_creds_len = strlen (tmp_creds); /* this is donated to the sspi */ user = calloc (tmp_creds_len + 1, sizeof (WCHAR)); user_len = MultiByteToWideChar ( CP_UTF8, 0, tmp_creds, tmp_creds_len, user, tmp_creds_len); user[user_len] = L'\0'; } state = (mongoc_sspi_client_state_t *) bson_malloc0 (sizeof *state); res = _mongoc_sspi_auth_sspi_client_init ( service, flags, user, user_len, NULL, 0, pass, pass_len, state); if (res != MONGOC_SSPI_AUTH_GSS_ERROR) { return state; } bson_free (state); return NULL; } /* *-------------------------------------------------------------------------- * * _mongoc_cluster_auth_node_sspi -- * * Perform authentication for a cluster node using SSPI * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * error may be set. * *-------------------------------------------------------------------------- */ bool _mongoc_cluster_auth_node_sspi (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error) { mongoc_cmd_parts_t parts; mongoc_sspi_client_state_t *state; uint8_t buf[4096] = {0}; bson_iter_t iter; uint32_t buflen; bson_t reply; char *tmpstr; int conv_id; bson_t cmd; int res = MONGOC_SSPI_AUTH_GSS_CONTINUE; int step; bool canonicalize = false; const bson_t *options; bson_t properties; char real_name[BSON_HOST_NAME_MAX + 1]; options = mongoc_uri_get_options (cluster->uri); if (bson_iter_init_find_case ( &iter, options, MONGOC_URI_CANONICALIZEHOSTNAME) && BSON_ITER_HOLDS_UTF8 (&iter)) { canonicalize = bson_iter_bool (&iter); } if (mongoc_uri_get_mechanism_properties (cluster->uri, &properties)) { if (bson_iter_init_find_case ( &iter, &properties, "CANONICALIZE_HOST_NAME") && BSON_ITER_HOLDS_UTF8 (&iter)) { canonicalize = !strcasecmp (bson_iter_utf8 (&iter, NULL), "true"); } bson_destroy (&properties); } if (canonicalize && _mongoc_sasl_get_canonicalized_name ( stream, real_name, sizeof real_name, error)) { state = _mongoc_cluster_sspi_new (cluster->uri, real_name); } else { state = _mongoc_cluster_sspi_new (cluster->uri, hostname); } if (!state) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "Couldn't initialize SSPI service."); goto failure; } for (step = 0;; step++) { mongoc_cmd_parts_init (&parts, "$external", MONGOC_QUERY_SLAVE_OK, &cmd); bson_init (&cmd); if (res == MONGOC_SSPI_AUTH_GSS_CONTINUE) { res = _mongoc_sspi_auth_sspi_client_step (state, buf); } else if (res == MONGOC_SSPI_AUTH_GSS_COMPLETE) { char *response; const char *tmp_creds = mongoc_uri_get_username (cluster->uri); int tmp_creds_len = strlen (tmp_creds); res = _mongoc_sspi_auth_sspi_client_unwrap (state, buf); response = bson_strdup (state->response); _mongoc_sspi_auth_sspi_client_wrap ( state, response, tmp_creds, tmp_creds_len, 0); bson_free (response); } if (res == MONGOC_SSPI_AUTH_GSS_ERROR) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "Received invalid SSPI data."); mongoc_cmd_parts_cleanup (&parts); bson_destroy (&cmd); break; } if (step == 0) { _mongoc_cluster_build_sasl_start ( &cmd, "GSSAPI", state->response, strlen (state->response)); } else { if (state->response) { _mongoc_cluster_build_sasl_continue ( &cmd, conv_id, state->response, strlen (state->response)); } else { _mongoc_cluster_build_sasl_continue (&cmd, conv_id, "", 0); } } if (!mongoc_cluster_run_command_private (cluster, &parts, stream, 0, &reply, error)) { mongoc_cmd_parts_cleanup (&parts); bson_destroy (&cmd); bson_destroy (&reply); break; } mongoc_cmd_parts_cleanup (&parts); bson_destroy (&cmd); if (bson_iter_init_find (&iter, &reply, "done") && bson_iter_as_bool (&iter)) { bson_destroy (&reply); break; } conv_id = _mongoc_cluster_get_conversation_id (&reply); if (!bson_iter_init_find (&iter, &reply, "payload") || !BSON_ITER_HOLDS_UTF8 (&iter)) { bson_destroy (&reply); bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "Received invalid SASL reply from MongoDB server."); break; } 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); break; } memcpy (buf, tmpstr, buflen); bson_destroy (&reply); } bson_free (state); failure: if (error->domain) { return false; } return true; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cluster.c0000664000175000017500000022572213210321137022725 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" #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-cluster-sasl-private.h" #endif #ifdef MONGOC_ENABLE_SSL #include "mongoc-ssl.h" #include "mongoc-ssl-private.h" #include "mongoc-stream-tls.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-stream-tls.h" #include "mongoc-thread-private.h" #include "mongoc-topology-private.h" #include "mongoc-trace-private.h" #include "mongoc-util-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-uri-private.h" #include "mongoc-rpc-private.h" #include "mongoc-compression-private.h" #include "mongoc-cmd-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) #define IS_NOT_COMMAND(name) (!!strcasecmp (command_name, name)) static mongoc_server_stream_t * mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster, uint32_t server_id, bool reconnect_ok, bson_error_t *error); static mongoc_server_stream_t * mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster, uint32_t server_id, 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); /* *-------------------------------------------------------------------------- * * _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 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; case MONGOC_OPCODE_COMPRESSED: mongoc_counter_op_egress_compressed_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 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; case MONGOC_OPCODE_COMPRESSED: mongoc_counter_op_ingress_compressed_inc (); break; default: BSON_ASSERT (false); break; } } size_t _mongoc_cluster_buffer_iovec (mongoc_iovec_t *iov, size_t iovcnt, int skip, char *buffer) { int n; size_t buffer_offset = 0; int total_iov_len = 0; int difference = 0; for (n = 0; n < iovcnt; n++) { total_iov_len += iov[n].iov_len; if (total_iov_len <= skip) { continue; } /* If this iovec starts before the skip, and takes the total count * beyond the skip, we need to figure out the portion of the iovec * we should skip passed */ if (total_iov_len - iov[n].iov_len < skip) { difference = skip - (total_iov_len - iov[n].iov_len); } else { difference = 0; } memcpy (buffer + buffer_offset, iov[n].iov_base + difference, iov[n].iov_len - difference); buffer_offset += iov[n].iov_len - difference; } return buffer_offset; } /* 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); } } #define RUN_CMD_ERR(_domain, _code, _msg) \ do { \ bson_set_error (error, _domain, _code, _msg); \ _bson_error_message_printf ( \ error, \ "Failed to send \"%s\" command with database \"%s\": %s", \ command_name, \ cmd->db_name, \ error->message); \ } while (0) /* *-------------------------------------------------------------------------- * * mongoc_cluster_run_command_internal -- * * 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. * *-------------------------------------------------------------------------- */ static bool mongoc_cluster_run_command_internal (mongoc_cluster_t *cluster, mongoc_cmd_t *cmd, mongoc_stream_t *stream, int32_t compressor_id, bool monitored, const mongoc_host_list_t *host, bson_t *reply, bson_error_t *error) { int64_t started; const char *command_name; mongoc_apm_callbacks_t *callbacks; const size_t reply_header_size = sizeof (mongoc_rpc_reply_header_t); uint8_t reply_header_buf[sizeof (mongoc_rpc_reply_header_t)]; uint8_t *reply_buf; /* reply body */ mongoc_rpc_t rpc; /* sent to server */ bson_error_t err_local; /* in case the passed-in "error" is NULL */ bson_t reply_local; bson_t *reply_ptr; char cmd_ns[MONGOC_NAMESPACE_MAX]; uint32_t request_id; int32_t msg_len; size_t doc_len; mongoc_apm_command_started_t started_event; mongoc_apm_command_succeeded_t succeeded_event; mongoc_apm_command_failed_t failed_event; bool ret = false; #ifdef MONGOC_ENABLE_COMPRESSION char *output = NULL; #endif ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (cmd); BSON_ASSERT (stream); started = bson_get_monotonic_time (); /* * setup */ reply_ptr = reply ? reply : &reply_local; bson_init (reply_ptr); callbacks = &cluster->client->apm_callbacks; if (!error) { error = &err_local; } error->code = 0; /* * prepare the request */ command_name = _mongoc_get_command_name (cmd->command); if (!command_name) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Empty command document"); /* haven't fired command-started event, so don't fire command-failed */ monitored = false; GOTO (done); } _mongoc_array_clear (&cluster->iov); bson_snprintf (cmd_ns, sizeof cmd_ns, "%s.$cmd", cmd->db_name); request_id = ++cluster->request_id; _mongoc_rpc_prep_command (&rpc, cmd_ns, cmd); rpc.header.request_id = request_id; _mongoc_cluster_inc_egress_rpc (&rpc); _mongoc_rpc_gather (&rpc, &cluster->iov); _mongoc_rpc_swab_to_le (&rpc); #ifdef MONGOC_ENABLE_COMPRESSION if (compressor_id && IS_NOT_COMMAND ("ismaster") && IS_NOT_COMMAND ("saslstart") && IS_NOT_COMMAND ("saslcontinue") && IS_NOT_COMMAND ("getnonce") && IS_NOT_COMMAND ("authenticate") && IS_NOT_COMMAND ("createuser") && IS_NOT_COMMAND ("updateuser") && IS_NOT_COMMAND ("copydbsaslstart") && IS_NOT_COMMAND ("copydbgetnonce") && IS_NOT_COMMAND ("copydb")) { output = _mongoc_rpc_compress (cluster, compressor_id, &rpc, error); if (output == NULL) { monitored = false; GOTO (done); } } #endif if (monitored && callbacks->started) { mongoc_apm_command_started_init (&started_event, cmd->command, cmd->db_name, command_name, request_id, cmd->operation_id, host, cmd->server_id, cluster->client->apm_context); callbacks->started (&started_event); mongoc_apm_command_started_cleanup (&started_event); } 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."); GOTO (done); } /* * send and receive */ if (!_mongoc_stream_writev_full (stream, cluster->iov.data, cluster->iov.len, cluster->sockettimeoutms, error)) { mongoc_cluster_disconnect_node (cluster, cmd->server_id, true, error); /* add info about the command to writev_full's error message */ _bson_error_message_printf ( error, "Failed to send \"%s\" command with database \"%s\": %s", command_name, cmd->db_name, error->message); GOTO (done); } if (reply_header_size != mongoc_stream_read (stream, &reply_header_buf, reply_header_size, reply_header_size, cluster->sockettimeoutms)) { RUN_CMD_ERR (MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "socket error or timeout"); mongoc_cluster_disconnect_node ( cluster, cmd->server_id, !mongoc_stream_timed_out (stream), error); GOTO (done); } memcpy (&msg_len, reply_header_buf, 4); msg_len = BSON_UINT32_FROM_LE (msg_len); if ((msg_len < reply_header_size) || (msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE)) { GOTO (done); } if (!_mongoc_rpc_scatter_reply_header_only ( &rpc, reply_header_buf, reply_header_size)) { GOTO (done); } doc_len = (size_t) msg_len - reply_header_size; if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_COMPRESSED) { bson_t tmp = BSON_INITIALIZER; uint8_t *buf = NULL; size_t len = BSON_UINT32_FROM_LE (rpc.compressed.uncompressed_size) + sizeof (mongoc_rpc_header_t); reply_buf = bson_malloc0 (msg_len); memcpy (reply_buf, reply_header_buf, reply_header_size); if (doc_len != mongoc_stream_read (stream, reply_buf + reply_header_size, doc_len, doc_len, cluster->sockettimeoutms)) { RUN_CMD_ERR (MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "socket error or timeout"); GOTO (done); } if (!_mongoc_rpc_scatter (&rpc, reply_buf, msg_len)) { GOTO (done); } buf = bson_malloc0 (len); if (!_mongoc_rpc_decompress (&rpc, buf, len)) { RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Could not decompress server reply"); bson_free (reply_buf); bson_free (buf); GOTO (done); } _mongoc_rpc_swab_from_le (&rpc); _mongoc_cluster_inc_ingress_rpc (&rpc); _mongoc_rpc_get_first_document (&rpc, &tmp); bson_copy_to (&tmp, reply_ptr); bson_free (reply_buf); bson_free (buf); } else if (BSON_UINT32_FROM_LE (rpc.header.opcode) == MONGOC_OPCODE_REPLY && BSON_UINT32_FROM_LE (rpc.reply_header.n_returned) == 1) { reply_buf = bson_reserve_buffer (reply_ptr, (uint32_t) doc_len); BSON_ASSERT (reply_buf); if (doc_len != mongoc_stream_read (stream, (void *) reply_buf, doc_len, doc_len, cluster->sockettimeoutms)) { RUN_CMD_ERR (MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "socket error or timeout"); GOTO (done); } _mongoc_rpc_swab_from_le (&rpc); } else { GOTO (done); } _mongoc_cluster_inc_ingress_rpc (&rpc); if (!_mongoc_cmd_check_ok ( reply_ptr, cluster->client->error_api_version, error)) { GOTO (done); } ret = true; if (monitored && callbacks->succeeded) { mongoc_apm_command_succeeded_init (&succeeded_event, bson_get_monotonic_time () - started, reply_ptr, command_name, request_id, cmd->operation_id, host, cmd->server_id, cluster->client->apm_context); callbacks->succeeded (&succeeded_event); mongoc_apm_command_succeeded_cleanup (&succeeded_event); } done: if (!ret && error->code == 0) { /* generic error */ RUN_CMD_ERR (MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply from server."); } if (!ret && monitored && callbacks->failed) { mongoc_apm_command_failed_init (&failed_event, bson_get_monotonic_time () - started, command_name, error, request_id, cmd->operation_id, host, cmd->server_id, cluster->client->apm_context); callbacks->failed (&failed_event); mongoc_apm_command_failed_cleanup (&failed_event); } if (reply_ptr == &reply_local) { bson_destroy (reply_ptr); } #ifdef MONGOC_ENABLE_COMPRESSION bson_free (output); #endif RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_run_command_monitored -- * * 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: * If the client's APM callbacks are set, they are executed. * @reply is set and should ALWAYS be released with bson_destroy(). * *-------------------------------------------------------------------------- */ bool mongoc_cluster_run_command_monitored (mongoc_cluster_t *cluster, mongoc_cmd_parts_t *parts, mongoc_server_stream_t *server_stream, bson_t *reply, bson_error_t *error) { int32_t compressor_id = #ifdef MONGOC_ENABLE_COMPRESSION mongoc_server_description_compressor_id (server_stream->sd); #else 0; #endif mongoc_cmd_parts_assemble (parts, server_stream); return mongoc_cluster_run_command_internal (cluster, &parts->assembled, server_stream->stream, compressor_id, true, &server_stream->sd->host, reply, error); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_run_command_private -- * * Internal function to run a command on a given stream. * @error and @reply are optional out-pointers. * The client's APM callbacks are not executed. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @reply is set and should ALWAYS be released with bson_destroy(). * *-------------------------------------------------------------------------- */ bool mongoc_cluster_run_command_private (mongoc_cluster_t *cluster, mongoc_cmd_parts_t *parts, mongoc_stream_t *stream, uint32_t server_id, bson_t *reply, bson_error_t *error) { mongoc_cmd_parts_assemble_simple (parts, server_id); /* monitored = false */ return mongoc_cluster_run_command_internal (cluster, &parts->assembled, stream, 0, /* not monitored */ false, NULL, reply, error); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_run_ismaster -- * * Run an ismaster command on the given stream. * * Returns: * A mongoc_server_description_t you must destroy. If the call failed * its error is set and its type is MONGOC_SERVER_UNKNOWN. * *-------------------------------------------------------------------------- */ static mongoc_server_description_t * _mongoc_stream_run_ismaster (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *address, uint32_t server_id) { const bson_t *command; mongoc_cmd_parts_t parts; bson_t reply; bson_error_t error = {0}; int64_t start; int64_t rtt_msec; mongoc_server_description_t *sd; bool r; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (stream); command = _mongoc_topology_scanner_get_ismaster ( cluster->client->topology->scanner); mongoc_cmd_parts_init (&parts, "admin", MONGOC_QUERY_SLAVE_OK, command); start = bson_get_monotonic_time (); mongoc_cluster_run_command_private ( cluster, &parts, stream, server_id, &reply, &error); rtt_msec = (bson_get_monotonic_time () - start) / 1000; sd = (mongoc_server_description_t *) bson_malloc0 ( sizeof (mongoc_server_description_t)); mongoc_server_description_init (sd, address, server_id); /* send the error from run_command IN to handle_ismaster */ mongoc_server_description_handle_ismaster (sd, &reply, rtt_msec, &error); bson_destroy (&reply); r = _mongoc_topology_update_from_handshake (cluster->client->topology, sd); if (!r) { mongoc_server_description_reset (sd); bson_set_error (&sd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NOT_ESTABLISHED, "\"%s\" removed from topology", address); } RETURN (sd); } /* *-------------------------------------------------------------------------- * * _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, updates cluster->topology->description * with ismaster result. * *-------------------------------------------------------------------------- */ static bool _mongoc_cluster_run_ismaster (mongoc_cluster_t *cluster, mongoc_cluster_node_t *node, uint32_t server_id, bson_error_t *error /* OUT */) { bool r; mongoc_server_description_t *sd; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (node); BSON_ASSERT (node->stream); sd = _mongoc_stream_run_ismaster ( cluster, node->stream, node->connection_address, server_id); if (sd->type == MONGOC_SERVER_UNKNOWN) { r = false; memcpy (error, &sd->error, sizeof (bson_error_t)); } else { r = true; node->max_write_batch_size = sd->max_write_batch_size; node->min_wire_version = sd->min_wire_version; node->max_wire_version = sd->max_wire_version; node->max_bson_obj_size = sd->max_bson_obj_size; node->max_msg_size = sd->max_msg_size; } mongoc_server_description_destroy (sd); return r; } /* *-------------------------------------------------------------------------- * * _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) { mongoc_cmd_parts_t parts; 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); mongoc_cmd_parts_init (&parts, auth_source, MONGOC_QUERY_SLAVE_OK, &command); if (!mongoc_cluster_run_command_private ( cluster, &parts, stream, 0, &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_private * checks for {ok: 1} in the response. */ mongoc_cmd_parts_cleanup (&parts); mongoc_cmd_parts_init (&parts, auth_source, MONGOC_QUERY_SLAVE_OK, &command); ret = mongoc_cluster_run_command_private ( cluster, &parts, stream, 0, &reply, error); if (!ret) { /* error->message is already set */ error->domain = MONGOC_ERROR_CLIENT; error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; } mongoc_cmd_parts_cleanup (&parts); bson_destroy (&command); bson_destroy (&reply); RETURN (ret); } /* *-------------------------------------------------------------------------- * * _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) { mongoc_cmd_parts_t parts; 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); mongoc_cmd_parts_init (&parts, "$external", MONGOC_QUERY_SLAVE_OK, &b); ret = mongoc_cluster_run_command_private ( cluster, &parts, stream, 0, &reply, error); if (!ret) { /* error->message is already set */ error->domain = MONGOC_ERROR_CLIENT; error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; } mongoc_cmd_parts_cleanup (&parts); 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) { mongoc_cmd_parts_t parts; const char *username_from_uri = NULL; char *username_from_subject = NULL; bson_t cmd; bson_t reply; bool ret; BSON_ASSERT (cluster); BSON_ASSERT (stream); username_from_uri = mongoc_uri_get_username (cluster->uri); if (username_from_uri) { TRACE ("%s", "X509: got username from URI"); } 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; } username_from_subject = mongoc_ssl_extract_subject ( cluster->client->ssl_opts.pem_file, cluster->client->ssl_opts.pem_pwd); if (!username_from_subject) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "No username provided for X509 authentication."); return false; } TRACE ("%s", "X509: got username from certificate"); } bson_init (&cmd); BSON_APPEND_INT32 (&cmd, "authenticate", 1); BSON_APPEND_UTF8 (&cmd, "mechanism", "MONGODB-X509"); BSON_APPEND_UTF8 (&cmd, "user", username_from_uri ? username_from_uri : username_from_subject); mongoc_cmd_parts_init (&parts, "$external", MONGOC_QUERY_SLAVE_OK, &cmd); ret = mongoc_cluster_run_command_private ( cluster, &parts, stream, 0, &reply, error); if (!ret) { /* error->message is already set */ error->domain = MONGOC_ERROR_CLIENT; error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; } if (username_from_subject) { bson_free (username_from_subject); } mongoc_cmd_parts_cleanup (&parts); bson_destroy (&cmd); bson_destroy (&reply); return ret; } #endif #ifdef MONGOC_ENABLE_CRYPTO static bool _mongoc_cluster_auth_node_scram (mongoc_cluster_t *cluster, mongoc_stream_t *stream, bson_error_t *error) { mongoc_cmd_parts_t parts; 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)); if (*cluster->scram_client_key) { _mongoc_scram_set_client_key ( &scram, cluster->scram_client_key, sizeof (cluster->scram_client_key)); } if (*cluster->scram_server_key) { _mongoc_scram_set_server_key ( &scram, cluster->scram_server_key, sizeof (cluster->scram_server_key)); } if (*cluster->scram_salted_password) { _mongoc_scram_set_salted_password ( &scram, cluster->scram_salted_password, sizeof (cluster->scram_salted_password)); } 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); } TRACE ("SCRAM: authenticating (step %d)", scram.step); mongoc_cmd_parts_init (&parts, auth_source, MONGOC_QUERY_SLAVE_OK, &cmd); if (!mongoc_cluster_run_command_private ( cluster, &parts, stream, 0, &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; } mongoc_cmd_parts_cleanup (&parts); 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_DEBUG ("SCRAM: authentication failed"); 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); } TRACE ("%s", "SCRAM: authenticated"); ret = true; memcpy (cluster->scram_client_key, scram.client_key, sizeof (cluster->scram_client_key)); memcpy (cluster->scram_server_key, scram.server_key, sizeof (cluster->scram_server_key)); memcpy (cluster->scram_salted_password, scram.salted_password, sizeof (cluster->scram_salted_password)); 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_CRYPTO 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. If @invalidate is * true, also mark the server Unknown in the topology description, * passing the error information from @why as the reason. * * 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, bool invalidate, const bson_error_t *why /* IN */) { 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); } } else { mongoc_set_rm (cluster->nodes, server_id); } if (invalidate) { mongoc_topology_invalidate_server (topology, server_id, why); } 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->connection_address); 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, const char *connection_address) { mongoc_cluster_node_t *node; if (!stream) { return NULL; } node = (mongoc_cluster_node_t *) bson_malloc0 (sizeof *node); node->stream = stream; node->connection_address = bson_strdup (connection_address); 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, uint32_t server_id, bson_error_t *error /* OUT */) { mongoc_host_list_t *host = NULL; mongoc_cluster_node_t *cluster_node = NULL; mongoc_stream_t *stream; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (!cluster->client->topology->single_threaded); host = _mongoc_topology_host_by_id (cluster->client->topology, server_id, error); if (!host) { GOTO (error); } TRACE ("Adding new server to cluster: %s", host->host_and_port); stream = _mongoc_client_create_stream (cluster->client, host, error); if (!stream) { MONGOC_WARNING ( "Failed connection to %s (%s)", host->host_and_port, error->message); GOTO (error); } /* take critical fields from a fresh ismaster */ cluster_node = _mongoc_cluster_node_new (stream, host->host_and_port); if (!_mongoc_cluster_run_ismaster ( cluster, cluster_node, server_id, error)) { GOTO (error); } if (cluster->requires_auth) { if (!_mongoc_cluster_auth_node (cluster, cluster_node->stream, host->host, cluster_node->max_wire_version, error)) { MONGOC_WARNING ("Failed authentication to %s (%s)", host->host_and_port, error->message); GOTO (error); } } mongoc_set_add (cluster->nodes, server_id, cluster_node); _mongoc_host_list_destroy_all (host); RETURN (stream); error: _mongoc_host_list_destroy_all (host); /* null ok */ if (cluster_node) { _mongoc_cluster_node_destroy (cluster_node); /* also destroys stream */ } RETURN (NULL); } static void node_not_found (mongoc_topology_t *topology, uint32_t server_id, bson_error_t *error /* OUT */) { mongoc_server_description_t *sd; if (!error) { return; } sd = mongoc_topology_server_by_id (topology, server_id, error); if (!sd) { return; } 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); } mongoc_server_description_destroy (sd); } static void stream_not_found (mongoc_topology_t *topology, uint32_t server_id, const char *connection_address, bson_error_t *error /* OUT */) { mongoc_server_description_t *sd; sd = mongoc_topology_server_by_id (topology, server_id, error); if (error) { if (sd && 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", connection_address); } } if (sd) { mongoc_server_description_destroy (sd); } } mongoc_server_stream_t * _mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, uint32_t server_id, bool reconnect_ok, bson_error_t *error /* OUT */) { mongoc_topology_t *topology; mongoc_server_stream_t *server_stream; bson_error_t err_local; /* if fetch_stream fails we need a place to receive error details and pass * them to mongoc_topology_invalidate_server. */ bson_error_t *err_ptr = error ? error : &err_local; 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, server_id, reconnect_ok, err_ptr); } else { server_stream = mongoc_cluster_fetch_stream_pooled ( cluster, server_id, reconnect_ok, err_ptr); } if (!server_stream) { /* Server Discovery And Monitoring Spec: "When an application operation * fails because of any network error besides a socket timeout, the * client MUST replace the server's description with a default * ServerDescription of type Unknown, and fill the ServerDescription's * error field with useful information." * * error was filled by fetch_stream_single/pooled, pass it to disconnect() */ mongoc_cluster_disconnect_node (cluster, server_id, true, err_ptr); } 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_server_stream_t *server_stream = NULL; bson_error_t err_local = {0}; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (server_id); if (!error) { error = &err_local; } server_stream = _mongoc_cluster_stream_for_server ( cluster, server_id, reconnect_ok, error); if (!server_stream) { /* failed */ mongoc_cluster_disconnect_node (cluster, server_id, true, error); } RETURN (server_stream); } static mongoc_server_stream_t * mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster, uint32_t server_id, bool reconnect_ok, bson_error_t *error /* OUT */) { mongoc_topology_t *topology; mongoc_server_description_t *sd; mongoc_stream_t *stream; mongoc_topology_scanner_node_t *scanner_node; int64_t expire_at; topology = cluster->client->topology; scanner_node = mongoc_topology_scanner_get_node (topology->scanner, server_id); BSON_ASSERT (scanner_node && !scanner_node->retired); stream = scanner_node->stream; if (stream) { sd = mongoc_topology_server_by_id (topology, server_id, error); if (!sd) { return NULL; } } else { if (!reconnect_ok) { stream_not_found ( topology, server_id, scanner_node->host.host_and_port, 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'", scanner_node->host.host_and_port); return NULL; } #ifdef MONGOC_ENABLE_SSL if (cluster->client->use_ssl) { bool r; mongoc_stream_t *tls_stream; for (tls_stream = stream; tls_stream->type != MONGOC_STREAM_TLS; tls_stream = mongoc_stream_get_base_stream (tls_stream)) { } r = mongoc_stream_tls_handshake_block ( tls_stream, scanner_node->host.host, (int32_t) topology->connect_timeout_msec * 1000, error); if (!r) { mongoc_topology_scanner_node_disconnect (scanner_node, true); return NULL; } } #endif sd = _mongoc_stream_run_ismaster ( cluster, stream, scanner_node->host.host_and_port, server_id); } if (sd->type == MONGOC_SERVER_UNKNOWN) { memcpy (error, &sd->error, sizeof *error); mongoc_server_description_destroy (sd); return NULL; } /* stream open but not auth'ed: first use since connect or reconnect */ if (cluster->requires_auth && !scanner_node->has_auth) { if (!_mongoc_cluster_auth_node (cluster, stream, sd->host.host, sd->max_wire_version, &sd->error)) { memcpy (error, &sd->error, sizeof *error); mongoc_server_description_destroy (sd); return NULL; } scanner_node->has_auth = true; } return mongoc_server_stream_new (topology->description.type, sd, stream); } static mongoc_server_stream_t * _mongoc_cluster_create_server_stream (mongoc_topology_t *topology, uint32_t server_id, mongoc_stream_t *stream, bson_error_t *error /* OUT */) { mongoc_server_description_t *sd; sd = mongoc_topology_server_by_id (topology, server_id, error); if (!sd) { return NULL; } return mongoc_server_stream_new ( _mongoc_topology_get_type (topology), sd, stream); } static mongoc_server_stream_t * mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster, uint32_t server_id, bool reconnect_ok, bson_error_t *error /* OUT */) { 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, server_id); topology = cluster->client->topology; if (cluster_node) { BSON_ASSERT (cluster_node->stream); timestamp = mongoc_topology_server_timestamp (topology, server_id); if (timestamp == -1 || cluster_node->timestamp < timestamp) { /* topology change or net error during background scan made us remove * or replace server description since node's birth. destroy node. */ mongoc_cluster_disconnect_node ( cluster, server_id, false /* invalidate */, NULL); } else { return _mongoc_cluster_create_server_stream ( topology, server_id, cluster_node->stream, error); } } /* no node, or out of date */ if (!reconnect_ok) { node_not_found (topology, server_id, error); return NULL; } stream = _mongoc_cluster_add_node (cluster, server_id, error); if (stream) { return _mongoc_cluster_create_server_stream ( topology, server_id, stream, error); } 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, MONGOC_URI_SOCKETTIMEOUTMS, MONGOC_DEFAULT_SOCKETTIMEOUTMS); cluster->socketcheckintervalms = mongoc_uri_get_option_as_int32 (uri, MONGOC_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)); cluster->operation_id = rand (); 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; uint32_t server_id; mongoc_topology_t *topology = cluster->client->topology; ENTRY; BSON_ASSERT (cluster); server_id = mongoc_topology_select_server_id (topology, optype, read_prefs, error); if (!server_id) { RETURN (NULL); } if (!mongoc_cluster_check_interval (cluster, server_id)) { /* Server Selection Spec: try once more */ server_id = mongoc_topology_select_server_id (topology, optype, read_prefs, error); if (!server_id) { RETURN (NULL); } } /* connect or reconnect to server if necessary */ server_stream = _mongoc_cluster_stream_for_server ( cluster, server_id, true /* reconnect_ok */, error); 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); } 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_check_interval -- * * Server Selection Spec: * * Only for single-threaded drivers. * * If a server is selected that has an existing connection that has been * idle for socketCheckIntervalMS, the driver MUST check the connection * with the "ping" command. If the ping succeeds, use the selected * connection. If not, set the server's type to Unknown and update the * Topology Description according to the Server Discovery and Monitoring * Spec, and attempt once more to select a server. * * Returns: * True if the check succeeded or no check was required, false if the * check failed. * * Side effects: * If a check fails, closes stream and may set server type Unknown. * *-------------------------------------------------------------------------- */ bool mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id) { mongoc_cmd_parts_t parts; mongoc_topology_t *topology; mongoc_topology_scanner_node_t *scanner_node; mongoc_stream_t *stream; int64_t now; bson_t command; bson_error_t error; bool r = true; 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)) { bson_set_error (&error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "connection closed"); mongoc_cluster_disconnect_node (cluster, server_id, true, &error); return false; } } if (scanner_node->last_used + (1000 * cluster->socketcheckintervalms) < now) { bson_init (&command); BSON_APPEND_INT32 (&command, "ping", 1); mongoc_cmd_parts_init (&parts, "admin", MONGOC_QUERY_SLAVE_OK, &command); r = mongoc_cluster_run_command_private ( cluster, &parts, stream, server_id, NULL, &error /* OUT */); mongoc_cmd_parts_cleanup (&parts); bson_destroy (&command); if (!r) { mongoc_cluster_disconnect_node (cluster, server_id, true, &error); } } return r; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_sendv_to_server -- * * Sends the given RPCs to the given server. * * Returns: * True if successful. * * Side effects: * @rpc 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 *rpc, mongoc_server_stream_t *server_stream, const mongoc_write_concern_t *write_concern, bson_error_t *error) { uint32_t server_id; mongoc_topology_scanner_node_t *scanner_node; const bson_t *b; mongoc_rpc_t gle; bool need_gle; char cmdname[140]; int32_t max_msg_size; bool ret = false; #ifdef MONGOC_ENABLE_COMPRESSION int32_t compressor_id = 0; char *output = NULL; #endif ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (rpc); 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."); GOTO (done); } if (!write_concern) { write_concern = cluster->client->write_concern; } _mongoc_array_clear (&cluster->iov); #ifdef MONGOC_ENABLE_COMPRESSION compressor_id = mongoc_server_description_compressor_id (server_stream->sd); #endif need_gle = _mongoc_rpc_needs_gle (rpc, write_concern); _mongoc_cluster_inc_egress_rpc (rpc); _mongoc_rpc_gather (rpc, &cluster->iov); _mongoc_rpc_swab_to_le (rpc); #ifdef MONGOC_ENABLE_COMPRESSION if (compressor_id) { output = _mongoc_rpc_compress (cluster, compressor_id, rpc, error); if (output == NULL) { GOTO (done); } } #endif max_msg_size = mongoc_server_stream_max_msg_size (server_stream); if (BSON_UINT32_FROM_LE (rpc->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.", BSON_UINT32_FROM_LE (rpc->header.msg_len), max_msg_size); GOTO (done); } if (need_gle) { gle.header.msg_len = 0; gle.header.request_id = ++cluster->request_id; gle.header.response_to = 0; gle.header.opcode = MONGOC_OPCODE_QUERY; gle.query.flags = MONGOC_QUERY_NONE; switch (BSON_UINT32_FROM_LE (rpc->header.opcode)) { case MONGOC_OPCODE_INSERT: DB_AND_CMD_FROM_COLLECTION (cmdname, rpc->insert.collection); break; case MONGOC_OPCODE_DELETE: DB_AND_CMD_FROM_COLLECTION (cmdname, rpc->delete_.collection); break; case MONGOC_OPCODE_UPDATE: DB_AND_CMD_FROM_COLLECTION (cmdname, rpc->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); } if (!_mongoc_stream_writev_full (server_stream->stream, cluster->iov.data, cluster->iov.len, cluster->sockettimeoutms, error)) { GOTO (done); } 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 (); } } ret = true; done: #ifdef MONGOC_ENABLE_COMPRESSION if (compressor_id) { bson_free (output); } #endif RETURN (ret); } /* *-------------------------------------------------------------------------- * * 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; bson_error_t err_local; 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); if (!error) { error = &err_local; } /* * 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, !mongoc_stream_timed_out (server_stream->stream), error); 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, true, error); 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_stream_timed_out (server_stream->stream), error); 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, true, error); mongoc_counter_protocol_ingress_error_inc (); RETURN (false); } if (BSON_UINT32_FROM_LE (rpc->header.opcode) == MONGOC_OPCODE_COMPRESSED) { uint8_t *buf = NULL; size_t len = BSON_UINT32_FROM_LE (rpc->compressed.uncompressed_size) + sizeof (mongoc_rpc_header_t); buf = bson_malloc0 (len); if (!_mongoc_rpc_decompress (rpc, buf, len)) { bson_free (buf); bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Could not decompress server reply"); RETURN (false); } _mongoc_buffer_destroy (buffer); _mongoc_buffer_init (buffer, buf, len, NULL, NULL); } _mongoc_rpc_swab_from_le (rpc); _mongoc_cluster_inc_ingress_rpc (rpc); RETURN (true); } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cmd-private.h0000664000175000017500000000451013210321137023452 0ustar jmikolajmikola/* * Copyright 2017 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. */ /* * Internal struct to represent a command we will send to the server - command * parameters are collected in a mongoc_cmd_parts_t until we know the server's * wire version and whether it is mongos, then we collect the parts into a * mongoc_cmd_t, and gather that into a mongoc_rpc_t. */ #ifndef MONGOC_CMD_PRIVATE_H #define MONGOC_CMD_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-server-stream-private.h" #include "mongoc-read-prefs.h" #include "mongoc.h" BSON_BEGIN_DECLS typedef struct _mongoc_cmd_t { const char *db_name; mongoc_query_flags_t query_flags; const bson_t *command; uint32_t server_id; int64_t operation_id; } mongoc_cmd_t; typedef struct _mongoc_cmd_parts_t { mongoc_cmd_t assembled; mongoc_query_flags_t user_query_flags; const bson_t *body; bson_t extra; const mongoc_read_prefs_t *read_prefs; bson_t assembled_body; bool is_write_command; } mongoc_cmd_parts_t; void mongoc_cmd_parts_init (mongoc_cmd_parts_t *op, const char *db_name, mongoc_query_flags_t user_query_flags, const bson_t *command_body); bool mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, bson_iter_t *iter, int max_wire_version, bson_error_t *error); void mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts, const mongoc_server_stream_t *server_stream); void mongoc_cmd_parts_assemble_simple (mongoc_cmd_parts_t *op, uint32_t server_id); void mongoc_cmd_parts_cleanup (mongoc_cmd_parts_t *op); BSON_END_DECLS #endif /* MONGOC_CMD_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cmd.c0000664000175000017500000002542613210321137022006 0ustar jmikolajmikola/* * Copyright 2017 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-cmd-private.h" #include "mongoc-read-prefs-private.h" #include "mongoc-trace-private.h" #include "mongoc-client-private.h" #include "mongoc-write-concern-private.h" /* For strcasecmp on Windows */ #include "mongoc-util-private.h" void mongoc_cmd_parts_init (mongoc_cmd_parts_t *parts, const char *db_name, mongoc_query_flags_t user_query_flags, const bson_t *command_body) { parts->body = command_body; parts->user_query_flags = user_query_flags; parts->read_prefs = NULL; parts->is_write_command = false; bson_init (&parts->extra); bson_init (&parts->assembled_body); parts->assembled.db_name = db_name; parts->assembled.command = NULL; parts->assembled.query_flags = MONGOC_QUERY_NONE; } /* *-------------------------------------------------------------------------- * * mongoc_cmd_parts_append_opts -- * * Take an iterator over user-supplied options document and append the * options to @parts->command_extra, taking the selected server's max * wire version into account. * * Return: * True if the options were successfully applied. If any options are * invalid, returns false and fills out @error. In that case @parts is * invalid and must not be used. * * Side effects: * May partly apply options before returning an error. * *-------------------------------------------------------------------------- */ bool mongoc_cmd_parts_append_opts (mongoc_cmd_parts_t *parts, bson_iter_t *iter, int max_wire_version, bson_error_t *error) { bool is_fam; ENTRY; /* not yet assembled */ BSON_ASSERT (!parts->assembled.command); is_fam = !strcasecmp (_mongoc_get_command_name (parts->body), "findandmodify"); while (bson_iter_next (iter)) { if (BSON_ITER_IS_KEY (iter, "collation")) { if (max_wire_version < WIRE_VERSION_COLLATION) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "The selected server does not support collation"); RETURN (false); } } else if (BSON_ITER_IS_KEY (iter, "writeConcern")) { if (!_mongoc_write_concern_iter_is_valid (iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Invalid writeConcern"); RETURN (false); } if ((is_fam && max_wire_version < WIRE_VERSION_FAM_WRITE_CONCERN) || (!is_fam && max_wire_version < WIRE_VERSION_CMD_WRITE_CONCERN)) { continue; } } else if (BSON_ITER_IS_KEY (iter, "readConcern")) { if (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"); RETURN (false); } } else if (BSON_ITER_IS_KEY (iter, "serverId")) { continue; } bson_append_iter (&parts->extra, bson_iter_key (iter), -1, iter); } RETURN (true); } /* Update result with the read prefs, following Server Selection Spec. * The driver must have discovered the server is a mongos. */ static void _cmd_parts_apply_read_preferences_mongos (mongoc_cmd_parts_t *parts) { mongoc_read_mode_t mode; const bson_t *tags = NULL; bson_t child; const char *mode_str; int64_t stale; mode = mongoc_read_prefs_get_mode (parts->read_prefs); if (parts->read_prefs) { tags = mongoc_read_prefs_get_tags (parts->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)) { parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK; } else if (mode != MONGOC_READ_PRIMARY) { parts->assembled.query_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. */ if (bson_has_field (parts->body, "$query")) { bson_concat (&parts->assembled_body, parts->body); } else { bson_append_document ( &parts->assembled_body, "$query", 6, parts->body); } bson_append_document_begin ( &parts->assembled_body, "$readPreference", 15, &child); mode_str = _mongoc_read_mode_as_str (mode); bson_append_utf8 (&child, "mode", 4, mode_str, -1); if (!bson_empty0 (tags)) { bson_append_array (&child, "tags", 4, tags); } stale = mongoc_read_prefs_get_max_staleness_seconds (parts->read_prefs); if (stale != MONGOC_NO_MAX_STALENESS) { bson_append_int64 (&child, "maxStalenessSeconds", 19, stale); } bson_append_document_end (&parts->assembled_body, &child); parts->assembled.command = &parts->assembled_body; } } /* *-------------------------------------------------------------------------- * * mongoc_cmd_parts_assemble -- * * Assemble the command body, options, and read preference into one * command. * * Side effects: * Sets @parts->command_ptr and @parts->query_flags. Concatenates * @parts->body and @parts->command_extra into @parts->assembled if * needed. * *-------------------------------------------------------------------------- */ void mongoc_cmd_parts_assemble (mongoc_cmd_parts_t *parts, const mongoc_server_stream_t *server_stream) { mongoc_server_description_type_t server_type; ENTRY; BSON_ASSERT (parts); BSON_ASSERT (server_stream); server_type = server_stream->sd->type; /* must not be assembled already */ BSON_ASSERT (!parts->assembled.command); BSON_ASSERT (bson_empty (&parts->assembled_body)); /* begin with raw flags/cmd as assembled flags/cmd, might change below */ parts->assembled.command = parts->body; parts->assembled.query_flags = parts->user_query_flags; parts->assembled.server_id = server_stream->sd->id; if (!parts->is_write_command) { switch (server_stream->topology_type) { case MONGOC_TOPOLOGY_SINGLE: if (server_type == MONGOC_SERVER_MONGOS) { _cmd_parts_apply_read_preferences_mongos (parts); } 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." */ parts->assembled.query_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 (parts->read_prefs && parts->read_prefs->mode != MONGOC_READ_PRIMARY) { parts->assembled.query_flags |= MONGOC_QUERY_SLAVE_OK; } break; case MONGOC_TOPOLOGY_SHARDED: _cmd_parts_apply_read_preferences_mongos (parts); break; case MONGOC_TOPOLOGY_UNKNOWN: case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: default: /* must not call mongoc_cmd_parts_assemble w/ unknown topology type */ BSON_ASSERT (false); } } /* if (!parts->is_write_command) */ if (!bson_empty (&parts->extra)) { /* Did we already copy the command body? */ if (parts->assembled.command == parts->body) { bson_concat (&parts->assembled_body, parts->body); bson_concat (&parts->assembled_body, &parts->extra); parts->assembled.command = &parts->assembled_body; } } EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_cmd_parts_assemble_simple -- * * Sets @parts->assembled.command and @parts->query_flags, without * applying any server-specific logic. * *-------------------------------------------------------------------------- */ void mongoc_cmd_parts_assemble_simple (mongoc_cmd_parts_t *parts, uint32_t server_id) { /* must not be assembled already, must have no options set */ BSON_ASSERT (!parts->assembled.command); BSON_ASSERT (bson_empty (&parts->assembled_body)); BSON_ASSERT (bson_empty (&parts->extra)); parts->assembled.query_flags = parts->user_query_flags; parts->assembled.command = parts->body; parts->assembled.server_id = server_id; } /* *-------------------------------------------------------------------------- * * mongoc_cmd_parts_cleanup -- * * Free memory associated with a stack-allocated mongoc_cmd_parts_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_cmd_parts_cleanup (mongoc_cmd_parts_t *parts) { bson_destroy (&parts->extra); bson_destroy (&parts->assembled_body); } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-collection-private.h0000664000175000017500000000335113210321137025044 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_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.3.4/src/libmongoc/src/mongoc/mongoc-collection.c0000664000175000017500000024023313210321137023371 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-private.h" #include "mongoc-read-concern-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-util-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 mongoc_cursor_t * _mongoc_collection_cursor_new (mongoc_collection_t *collection, mongoc_query_flags_t flags, const mongoc_read_prefs_t *prefs) { return _mongoc_cursor_new (collection->client, collection->ns, flags, 0, /* skip */ 0, /* limit */ 0, /* batch_size */ false, /* is_command */ NULL, /* query */ NULL, /* fields */ prefs, /* 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 *opts, /* IN */ const mongoc_read_prefs_t *read_prefs) /* IN */ { mongoc_cmd_parts_t parts; mongoc_server_stream_t *server_stream = NULL; bool has_batch_size = false; bool has_out_key = false; bson_iter_t kiter; bson_iter_t ar; mongoc_cursor_t *cursor; uint32_t server_id; int32_t batch_size = 0; bson_iter_t iter; bson_t command; bson_t child; 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, read_prefs); mongoc_cmd_parts_init (&parts, collection->db, flags, &command); parts.read_prefs = read_prefs; if (!_mongoc_read_prefs_validate (cursor->read_prefs, &cursor->error)) { GOTO (done); } if (!_mongoc_get_server_id_from_opts (opts, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, &server_id, &cursor->error)) { GOTO (done); } if (server_id) { /* will set slaveok bit if server is not mongos */ mongoc_cursor_set_hint (cursor, server_id); /* server id isn't enough. ensure we're connected & know wire version */ server_stream = mongoc_cluster_stream_for_server (&collection->client->cluster, cursor->server_id, true /* reconnect ok */, &cursor->error); if (!server_stream) { GOTO (done); } } else { server_stream = mongoc_cluster_stream_for_reads ( &collection->client->cluster, read_prefs, &cursor->error); if (!server_stream) { GOTO (done); } /* don't use mongoc_cursor_set_hint, don't want special slaveok logic */ cursor->server_id = server_stream->sd->id; } use_cursor = server_stream->sd->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); } if (bson_iter_init_find (&iter, pipeline, "pipeline") && 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, &kiter)) { has_out_key |= bson_iter_find (&kiter, "$out"); } } } /* for newer version, we include a cursor subdocument */ if (use_cursor) { bson_append_document_begin (&command, "cursor", 6, &child); if (opts && bson_iter_init_find (&iter, opts, "batchSize") && BSON_ITER_HOLDS_NUMBER (&iter)) { batch_size = (int32_t) bson_iter_as_int64 (&iter); BSON_APPEND_INT32 (&child, "batchSize", batch_size); has_batch_size = true; } bson_append_document_end (&command, &child); } if (opts) { bool ok = false; bson_t opts_dupe = BSON_INITIALIZER; if (has_batch_size || server_stream->sd->max_wire_version == 0) { bson_copy_to_excluding_noinit (opts, &opts_dupe, "batchSize", NULL); bson_iter_init (&iter, &opts_dupe); } else { bson_iter_init (&iter, opts); } /* omits "serverId" */ ok = mongoc_cmd_parts_append_opts ( &parts, &iter, server_stream->sd->max_wire_version, &cursor->error); bson_destroy (&opts_dupe); if (!ok) { GOTO (done); } } /* Only inherit WriteConcern when for aggregate with $out */ if (!bson_has_field (&parts.extra, "writeConcern") && has_out_key) { mongoc_write_concern_destroy (cursor->write_concern); cursor->write_concern = mongoc_write_concern_copy ( mongoc_collection_get_write_concern (collection)); } if (!bson_has_field (&parts.extra, "readConcern")) { mongoc_read_concern_destroy (cursor->read_concern); cursor->read_concern = mongoc_read_concern_copy ( mongoc_collection_get_read_concern (collection)); 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 (&parts.extra, "readConcern", read_concern_bson); } } mongoc_cmd_parts_assemble (&parts, server_stream); if (use_cursor) { _mongoc_cursor_cursorid_init (cursor, parts.assembled.command); } else { /* for older versions we get an array that we can create a synthetic * cursor on top of */ _mongoc_cursor_array_init (cursor, parts.assembled.command, "result"); } done: mongoc_server_stream_cleanup (server_stream); /* null ok */ mongoc_cmd_parts_cleanup (&parts); 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 -- * * DEPRECATED: use mongoc_collection_find_with_opts. * * 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, COALESCE (read_prefs, collection->read_prefs), collection->read_concern); } /* *-------------------------------------------------------------------------- * * mongoc_collection_find_with_opts -- * * Create a cursor with a query filter. All other options are * specified in a free-form BSON document. * * Parameters: * @collection: A mongoc_collection_t. * @filter: The query to locate matching documents. * @opts: Other options. * @read_prefs: Optional 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_with_opts (mongoc_collection_t *collection, const bson_t *filter, const bson_t *opts, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (collection); BSON_ASSERT (filter); bson_clear (&collection->gle); if (!read_prefs) { read_prefs = collection->read_prefs; } return _mongoc_cursor_new_with_opts ( collection->client, collection->ns, false /* is_command */, filter, opts, COALESCE (read_prefs, collection->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_read_command_with_opts (mongoc_collection_t *collection, const bson_t *command, const mongoc_read_prefs_t *read_prefs, const bson_t *opts, bson_t *reply, bson_error_t *error) { BSON_ASSERT (collection); return _mongoc_client_command_with_opts ( collection->client, collection->db, command, MONGOC_CMD_READ, opts, MONGOC_QUERY_NONE, COALESCE (read_prefs, collection->read_prefs), collection->read_concern, collection->write_concern, reply, error); } bool mongoc_collection_write_command_with_opts (mongoc_collection_t *collection, const bson_t *command, const bson_t *opts, bson_t *reply, bson_error_t *error) { BSON_ASSERT (collection); return _mongoc_client_command_with_opts (collection->client, collection->db, command, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, collection->read_prefs, collection->read_concern, collection->write_concern, reply, error); } bool mongoc_collection_read_write_command_with_opts ( mongoc_collection_t *collection, const bson_t *command, const mongoc_read_prefs_t *read_prefs /* IGNORED */, const bson_t *opts, bson_t *reply, bson_error_t *error) { BSON_ASSERT (collection); return _mongoc_client_command_with_opts ( collection->client, collection->db, command, MONGOC_CMD_RW, opts, MONGOC_QUERY_NONE, COALESCE (read_prefs, collection->read_prefs), collection->read_concern, collection->write_concern, reply, error); } 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 */ { int64_t ret; bson_t opts = BSON_INITIALIZER; /* Complex types must be parts of `opts`, otherwise we can't * follow various specs that require validation etc */ if (collection->read_concern->level != NULL) { const bson_t *read_concern_bson; read_concern_bson = _mongoc_read_concern_get_bson (collection->read_concern); BSON_APPEND_DOCUMENT (&opts, "readConcern", read_concern_bson); } /* Server Selection Spec: "may-use-secondary" commands SHOULD take a read * preference argument and otherwise MUST use the default read preference * from client, database or collection configuration. */ ret = mongoc_collection_count_with_opts ( collection, flags, query, skip, limit, &opts, read_prefs, error); bson_destroy (&opts); return ret; } 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 */ { bson_iter_t iter; int64_t ret = -1; bool success; bson_t reply; bson_t cmd = BSON_INITIALIZER; bson_t q; ENTRY; BSON_ASSERT (collection); 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); } success = _mongoc_client_command_with_opts ( collection->client, collection->db, &cmd, MONGOC_CMD_READ, opts, flags, COALESCE (read_prefs, collection->read_prefs), collection->read_concern, collection->write_concern, &reply, error); if (success) { if (bson_iter_init_find (&iter, &reply, "n")) { ret = bson_iter_as_int64 (&iter); } } bson_destroy (&reply); bson_destroy (&cmd); 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 */ { return mongoc_collection_drop_with_opts (collection, NULL, error); } bool mongoc_collection_drop_with_opts (mongoc_collection_t *collection, const bson_t *opts, bson_error_t *error) { bool ret; bson_t cmd; BSON_ASSERT (collection); bson_init (&cmd); bson_append_utf8 ( &cmd, "drop", 4, collection->collection, collection->collectionlen); ret = _mongoc_client_command_with_opts (collection->client, collection->db, &cmd, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, collection->read_prefs, collection->read_concern, collection->write_concern, NULL, /* reply */ 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 */ { return mongoc_collection_drop_index_with_opts ( collection, index_name, NULL, error); } bool mongoc_collection_drop_index_with_opts (mongoc_collection_t *collection, const char *index_name, const bson_t *opts, bson_error_t *error) { 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_client_command_with_opts (collection->client, collection->db, &cmd, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, collection->read_prefs, collection->read_concern, collection->write_concern, NULL, /* reply */ 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); 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) { bson_t reply; bool ret; BEGIN_IGNORE_DEPRECATIONS ret = mongoc_collection_create_index_with_opts ( collection, keys, opt, NULL, &reply, error); END_IGNORE_DEPRECATIONS bson_destroy (&reply); return ret; } bool mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, const bson_t *opts, bson_t *reply, bson_error_t *error) { mongoc_cmd_parts_t parts; 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 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; bool reply_initialized = false; bool has_collation = false; mongoc_server_stream_t *server_stream = NULL; bson_iter_t iter; mongoc_cluster_t *cluster; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (keys); def_opt = mongoc_index_opt_get_default (); opt = opt ? opt : def_opt; mongoc_cmd_parts_init (&parts, collection->db, MONGOC_QUERY_NONE, &cmd); parts.is_write_command = true; /* * 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"); GOTO (done); } } /* * 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->collation) { BSON_APPEND_DOCUMENT (&doc, "collation", opt->collation); has_collation = true; } 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); server_stream = mongoc_cluster_stream_for_reads ( &collection->client->cluster, NULL, error); if (!server_stream) { GOTO (done); } if (opts && bson_iter_init (&iter, opts)) { if (!mongoc_cmd_parts_append_opts ( &parts, &iter, server_stream->sd->max_wire_version, error)) { GOTO (done); } } if (has_collation && server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "The selected server does not support collation"); GOTO (done); } cluster = &collection->client->cluster; ret = mongoc_cluster_run_command_monitored ( cluster, &parts, server_stream, reply, &local_error); reply_initialized = true; if (ret) { if (reply) { ret = !_mongoc_parse_wc_err (reply, error); } } else { /* * 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 (local_error.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND) { if (has_collation) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "The selected server does not support collation"); } ret = _mongoc_collection_create_index_legacy ( collection, keys, opt, error); /* Clear the error reply from the first request */ if (reply) { bson_reinit (reply); } } else if (error) { memcpy (error, &local_error, sizeof *error); } } done: bson_destroy (&cmd); bson_free (alloc_name); mongoc_server_stream_cleanup (server_stream); mongoc_cmd_parts_cleanup (&parts); if (!reply_initialized && reply) { bson_init (reply); } 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) { BEGIN_IGNORE_DEPRECATIONS return mongoc_collection_create_index (collection, keys, opt, error); END_IGNORE_DEPRECATIONS } 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); /* Index Enumeration Spec: "run listIndexes on the primary node". */ read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor = mongoc_collection_find_with_opts ( idx_collection, &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); /* Set slaveOk but no read preference: Index Enumeration Spec says * "listIndexes can be run on a secondary" when directly connected but * "run listIndexes on the primary node in replicaSet mode". */ cursor = _mongoc_collection_cursor_new ( collection, MONGOC_QUERY_SLAVE_OK, NULL /* read prefs */); _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, NULL /* read prefs */); _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); } else { /* other error, to be handled by caller */ cursor = NULL; } } } 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; uint32_t i; bool ret; BSON_ASSERT (collection); BSON_ASSERT (documents); if (!write_concern) { write_concern = collection->write_concern; } if (!(flags & MONGOC_INSERT_NO_VALIDATE)) { for (i = 0; i < n_documents; i++) { if (!_mongoc_validate_new_document (documents[i], error)) { 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, ++collection->client->cluster.operation_id, 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->client->error_api_version, write_concern, /* no error domain override */ (mongoc_error_domain_t) 0, 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) && !_mongoc_validate_new_document (document, error)) { RETURN (false); } _mongoc_write_result_init (&result); _mongoc_write_command_init_insert ( &command, document, write_flags, ++collection->client->cluster.operation_id, false); _mongoc_collection_write_command_execute ( &command, collection, write_concern, &result); collection->gle = bson_new (); ret = _mongoc_write_result_complete (&result, collection->client->error_api_version, write_concern, /* no error domain override */ (mongoc_error_domain_t) 0, 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; bool ret; int flags = uflags; bson_t opts; 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)) { if (bson_iter_key (&iter)[0] == '$') { /* update document, all keys must be $-operators */ if (!_mongoc_validate_update (update, error)) { return false; } } else { if (!_mongoc_validate_replace (update, error)) { return false; } } } bson_init (&opts); BSON_APPEND_BOOL (&opts, "upsert", !!(flags & MONGOC_UPDATE_UPSERT)); BSON_APPEND_BOOL (&opts, "multi", !!(flags & MONGOC_UPDATE_MULTI_UPDATE)); _mongoc_write_result_init (&result); _mongoc_write_command_init_update ( &command, selector, update, &opts, write_flags, ++collection->client->cluster.operation_id); bson_destroy (&opts); _mongoc_collection_write_command_execute ( &command, collection, write_concern, &result); collection->gle = bson_new (); ret = _mongoc_write_result_complete (&result, collection->client->error_api_version, write_concern, /* no error domain override */ (mongoc_error_domain_t) 0, 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 false; } /* this document will be inserted, validate same as for inserts */ if (!_mongoc_validate_new_document (document, error)) { return false; } ret = mongoc_collection_update (collection, MONGOC_UPDATE_UPSERT | MONGOC_UPDATE_NO_VALIDATE, &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; bson_t opts; bool ret; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (selector); bson_clear (&collection->gle); if (!write_concern) { write_concern = collection->write_concern; } bson_init (&opts); BSON_APPEND_INT32 ( &opts, "limit", flags & MONGOC_REMOVE_SINGLE_REMOVE ? 1 : 0); _mongoc_write_result_init (&result); ++collection->client->cluster.operation_id; _mongoc_write_command_init_delete (&command, selector, &opts, write_flags, collection->client->cluster.operation_id); bson_destroy (&opts); _mongoc_collection_write_command_execute ( &command, collection, write_concern, &result); collection->gle = bson_new (); ret = _mongoc_write_result_complete (&result, collection->client->error_api_version, write_concern, 0 /* no error domain override */, 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 a bulk result. * * 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 = false; bool reply_initialized = false; 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."); goto cleanup; } 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); reply_initialized = true; cleanup: bson_destroy (&cmd); if (reply && !reply_initialized) { bson_init (reply); } 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) { return mongoc_collection_rename_with_opts ( collection, new_db, new_name, drop_target_before_rename, NULL, error); } bool mongoc_collection_rename_with_opts (mongoc_collection_t *collection, const char *new_db, const char *new_name, bool drop_target_before_rename, const bson_t *opts, 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 (strchr (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_with_opts (collection->client, "admin", &cmd, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, collection->read_prefs, collection->read_concern, collection->write_concern, NULL, /* reply */ 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); } /* Server Selection Spec: "may-use-secondary" commands SHOULD take a read * preference argument and otherwise MUST use the default read preference * from client, database or collection configuration. */ ret = mongoc_collection_command_simple ( collection, &cmd, collection->read_prefs, 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_cmd_parts_t parts; mongoc_server_stream_t *server_stream; bson_iter_t iter; bson_iter_t inner; const char *name; bson_t reply_local; bson_t *reply_ptr; bool ret; bson_t command = BSON_INITIALIZER; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (query); reply_ptr = reply ? reply : &reply_local; bson_init (reply_ptr); 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 (opts->max_time_ms > 0) { BSON_APPEND_INT32 (&command, "maxTimeMS", opts->max_time_ms); } if (!bson_has_field (&opts->extra, "writeConcern")) { 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_is_acknowledged (collection->write_concern)) { _BSON_APPEND_WRITE_CONCERN (&command, collection->write_concern); } } } mongoc_cmd_parts_init (&parts, collection->db, MONGOC_QUERY_NONE, &command); parts.is_write_command = true; if (bson_iter_init (&iter, &opts->extra)) { bool ok = mongoc_cmd_parts_append_opts ( &parts, &iter, server_stream->sd->max_wire_version, error); if (!ok) { bson_destroy (&command); mongoc_server_stream_cleanup (server_stream); RETURN (false); } } parts.assembled.operation_id = ++cluster->operation_id; ret = mongoc_cluster_run_command_monitored ( cluster, &parts, server_stream, reply_ptr, error); if (bson_iter_init_find (&iter, reply_ptr, "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); ret = false; } if (reply_ptr == &reply_local) { bson_destroy (reply_ptr); } mongoc_cmd_parts_cleanup (&parts); 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.3.4/src/libmongoc/src/mongoc/mongoc-collection.h0000664000175000017500000003036413210321137023400 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-macros.h" #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_EXPORT (mongoc_cursor_t *) mongoc_collection_aggregate (mongoc_collection_t *collection, mongoc_query_flags_t flags, const bson_t *pipeline, const bson_t *opts, const mongoc_read_prefs_t *read_prefs) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (void) mongoc_collection_destroy (mongoc_collection_t *collection); MONGOC_EXPORT (mongoc_collection_t *) mongoc_collection_copy (mongoc_collection_t *collection); MONGOC_EXPORT (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; MONGOC_EXPORT (bool) mongoc_collection_read_command_with_opts (mongoc_collection_t *collection, const bson_t *command, const mongoc_read_prefs_t *read_prefs, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_collection_write_command_with_opts (mongoc_collection_t *collection, const bson_t *command, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_collection_read_write_command_with_opts ( mongoc_collection_t *collection, const bson_t *command, const mongoc_read_prefs_t *read_prefs /* IGNORED */, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (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); MONGOC_EXPORT (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); MONGOC_EXPORT (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); MONGOC_EXPORT (bool) mongoc_collection_drop (mongoc_collection_t *collection, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_collection_drop_with_opts (mongoc_collection_t *collection, const bson_t *opts, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_collection_drop_index (mongoc_collection_t *collection, const char *index_name, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_collection_drop_index_with_opts (mongoc_collection_t *collection, const char *index_name, const bson_t *opts, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_collection_create_index (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, bson_error_t *error) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (bool) mongoc_collection_create_index_with_opts (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, const bson_t *opts, bson_t *reply, bson_error_t *error) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (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; MONGOC_EXPORT (mongoc_cursor_t *) mongoc_collection_find_indexes (mongoc_collection_t *collection, bson_error_t *error); MONGOC_EXPORT (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_DEPRECATED_FOR (mongoc_collection_find_with_opts) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (mongoc_cursor_t *) mongoc_collection_find_with_opts (mongoc_collection_t *collection, const bson_t *filter, const bson_t *opts, const mongoc_read_prefs_t *read_prefs) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (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_EXPORT (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); MONGOC_EXPORT (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); MONGOC_EXPORT (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); MONGOC_EXPORT (bool) mongoc_collection_save (mongoc_collection_t *collection, const bson_t *document, const mongoc_write_concern_t *write_concern, bson_error_t *error) BSON_GNUC_DEPRECATED_FOR (mongoc_collection_insert or mongoc_collection_update); MONGOC_EXPORT (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_EXPORT (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); MONGOC_EXPORT (bool) mongoc_collection_rename_with_opts (mongoc_collection_t *collection, const char *new_db, const char *new_name, bool drop_target_before_rename, const bson_t *opts, bson_error_t *error); MONGOC_EXPORT (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_EXPORT (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_EXPORT (bool) mongoc_collection_stats (mongoc_collection_t *collection, const bson_t *options, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (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; MONGOC_EXPORT (const mongoc_read_prefs_t *) mongoc_collection_get_read_prefs (const mongoc_collection_t *collection); MONGOC_EXPORT (void) mongoc_collection_set_read_prefs (mongoc_collection_t *collection, const mongoc_read_prefs_t *read_prefs); MONGOC_EXPORT (const mongoc_read_concern_t *) mongoc_collection_get_read_concern (const mongoc_collection_t *collection); MONGOC_EXPORT (void) mongoc_collection_set_read_concern (mongoc_collection_t *collection, const mongoc_read_concern_t *read_concern); MONGOC_EXPORT (const mongoc_write_concern_t *) mongoc_collection_get_write_concern (const mongoc_collection_t *collection); MONGOC_EXPORT (void) mongoc_collection_set_write_concern ( mongoc_collection_t *collection, const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (const char *) mongoc_collection_get_name (mongoc_collection_t *collection); MONGOC_EXPORT (const bson_t *) mongoc_collection_get_last_error (const mongoc_collection_t *collection); MONGOC_EXPORT (char *) mongoc_collection_keys_to_index_string (const bson_t *keys); MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-compression-private.h0000664000175000017500000000350513210321137025253 0ustar jmikolajmikola/* * Copyright 2017 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_COMPRESSION_PRIVATE_H #define MONGOC_COMPRESSION_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include /* Compressor IDs */ #define MONGOC_COMPRESSOR_NOOP_ID 0 #define MONGOC_COMPRESSOR_NOOP_STR "noop" #define MONGOC_COMPRESSOR_SNAPPY_ID 1 #define MONGOC_COMPRESSOR_SNAPPY_STR "snappy" #define MONGOC_COMPRESSOR_ZLIB_ID 2 #define MONGOC_COMPRESSOR_ZLIB_STR "zlib" BSON_BEGIN_DECLS size_t mongoc_compressor_max_compressed_length (int32_t compressor_id, size_t size); bool mongoc_compressor_supported (const char *compressor); const char * mongoc_compressor_id_to_name (int32_t compressor_id); int mongoc_compressor_name_to_id (const char *compressor); bool mongoc_uncompress (int32_t compressor_id, const uint8_t *compressed, size_t compressed_len, uint8_t *uncompressed, size_t *uncompressed_size); bool mongoc_compress (int32_t compressor_id, int32_t compression_level, char *uncompressed, size_t uncompressed_len, char *compressed, size_t *compressed_len); BSON_END_DECLS #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-compression.c0000664000175000017500000001236113210321137023576 0ustar jmikolajmikola/* * Copyright 2017 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" #include "mongoc-compression-private.h" #include "mongoc-trace-private.h" #include "mongoc-util-private.h" #ifdef MONGOC_ENABLE_COMPRESSION #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB #include #endif #ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY #include #endif #endif size_t mongoc_compressor_max_compressed_length (int32_t compressor_id, size_t size) { switch (compressor_id) { #ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY case MONGOC_COMPRESSOR_SNAPPY_ID: return snappy_max_compressed_length (size); break; #endif #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB case MONGOC_COMPRESSOR_ZLIB_ID: return compressBound (size); break; #endif case MONGOC_COMPRESSOR_NOOP_ID: return size; break; default: return 0; } } bool mongoc_compressor_supported (const char *compressor) { #ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY if (!strcasecmp (compressor, MONGOC_COMPRESSOR_SNAPPY_STR)) { return true; } #endif #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB if (!strcasecmp (compressor, MONGOC_COMPRESSOR_ZLIB_STR)) { return true; } #endif if (!strcasecmp (compressor, MONGOC_COMPRESSOR_NOOP_STR)) { return true; } return false; } const char * mongoc_compressor_id_to_name (int32_t compressor_id) { switch (compressor_id) { case MONGOC_COMPRESSOR_SNAPPY_ID: return MONGOC_COMPRESSOR_SNAPPY_STR; case MONGOC_COMPRESSOR_ZLIB_ID: return MONGOC_COMPRESSOR_ZLIB_STR; case MONGOC_COMPRESSOR_NOOP_ID: return MONGOC_COMPRESSOR_NOOP_STR; default: return "unknown"; } } int mongoc_compressor_name_to_id (const char *compressor) { #ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY if (strcasecmp (MONGOC_COMPRESSOR_SNAPPY_STR, compressor) == 0) { return MONGOC_COMPRESSOR_SNAPPY_ID; } #endif #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB if (strcasecmp (MONGOC_COMPRESSOR_ZLIB_STR, compressor) == 0) { return MONGOC_COMPRESSOR_ZLIB_ID; } #endif if (strcasecmp (MONGOC_COMPRESSOR_NOOP_STR, compressor) == 0) { return MONGOC_COMPRESSOR_NOOP_ID; } return -1; } bool mongoc_uncompress (int32_t compressor_id, const uint8_t *compressed, size_t compressed_len, uint8_t *uncompressed, size_t *uncompressed_size) { switch (compressor_id) { case MONGOC_COMPRESSOR_SNAPPY_ID: { #ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY snappy_status status; status = snappy_uncompress ((const char *) compressed, compressed_len, (char *) uncompressed, uncompressed_size); return status == SNAPPY_OK; #else MONGOC_WARNING ("Received snappy compressed opcode, but snappy " "compression is not compiled in"); return false; #endif break; } case MONGOC_COMPRESSOR_ZLIB_ID: { #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB int ok; ok = uncompress (uncompressed, (unsigned long *) uncompressed_size, compressed, compressed_len); return ok == Z_OK; #else MONGOC_WARNING ("Received zlib compressed opcode, but zlib " "compression is not compiled in"); return false; #endif break; } default: MONGOC_WARNING ("Unknown compressor ID %d", compressor_id); } return false; } bool mongoc_compress (int32_t compressor_id, int32_t compression_level, char *uncompressed, size_t uncompressed_len, char *compressed, size_t *compressed_len) { switch (compressor_id) { case MONGOC_COMPRESSOR_SNAPPY_ID: #ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY /* No compression_level option for snappy */ return snappy_compress ( uncompressed, uncompressed_len, compressed, compressed_len) == SNAPPY_OK; break; #else MONGOC_ERROR ("Client attempting to use compress with snappy, but snappy " "compression is not compiled in"); return false; #endif case MONGOC_COMPRESSOR_ZLIB_ID: #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB return compress2 ((unsigned char *) compressed, (unsigned long *) compressed_len, (unsigned char *) uncompressed, uncompressed_len, compression_level) == Z_OK; break; #else MONGOC_ERROR ("Client attempting to use compress with zlib, but zlib " "compression is not compiled in"); return false; #endif default: return false; } } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-config.h0000664000175000017500000001463213210321137022512 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_USER_SET_CFLAGS is set from config based on what compiler flags were * used to compile mongoc */ #define MONGOC_USER_SET_CFLAGS "-g -O0" #define MONGOC_USER_SET_LDFLAGS "" /* MONGOC_CC is used to determine what C compiler was used to compile mongoc */ #define MONGOC_CC "cc" /* * MONGOC_ENABLE_SSL_SECURE_CHANNEL is set from configure to determine if we are * compiled with Native SSL support on Windows */ #define MONGOC_ENABLE_SSL_SECURE_CHANNEL 0 #if MONGOC_ENABLE_SSL_SECURE_CHANNEL != 1 # undef MONGOC_ENABLE_SSL_SECURE_CHANNEL #endif /* * MONGOC_ENABLE_CRYPTO_CNG is set from configure to determine if we are * compiled with Native Crypto support on Windows */ #define MONGOC_ENABLE_CRYPTO_CNG 0 #if MONGOC_ENABLE_CRYPTO_CNG != 1 # undef MONGOC_ENABLE_CRYPTO_CNG #endif /* * MONGOC_ENABLE_SSL_SECURE_TRANSPORT is set from configure to determine if we are * compiled with Native SSL support on Darwin */ #define MONGOC_ENABLE_SSL_SECURE_TRANSPORT 0 #if MONGOC_ENABLE_SSL_SECURE_TRANSPORT != 1 # undef MONGOC_ENABLE_SSL_SECURE_TRANSPORT #endif /* * MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are * compiled with Native Crypto support on Darwin */ #define MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO 0 #if MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO #endif /* * MONGOC_ENABLE_SSL_LIBRESSL is set from configure to determine if we are * compiled with LibreSSL support. */ #define MONGOC_ENABLE_SSL_LIBRESSL 0 #if MONGOC_ENABLE_SSL_LIBRESSL != 1 # undef MONGOC_ENABLE_SSL_LIBRESSL #endif /* * MONGOC_ENABLE_SSL_OPENSSL is set from configure to determine if we are * compiled with OpenSSL support. */ #define MONGOC_ENABLE_SSL_OPENSSL 1 #if MONGOC_ENABLE_SSL_OPENSSL != 1 # undef MONGOC_ENABLE_SSL_OPENSSL #endif /* * MONGOC_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are * compiled with OpenSSL support. */ #define MONGOC_ENABLE_CRYPTO_LIBCRYPTO 1 #if MONGOC_ENABLE_CRYPTO_LIBCRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO_LIBCRYPTO #endif /* * MONGOC_ENABLE_SSL is set from configure to determine if we are * compiled with any SSL support. */ #define MONGOC_ENABLE_SSL 1 #if MONGOC_ENABLE_SSL != 1 # undef MONGOC_ENABLE_SSL #endif /* * MONGOC_ENABLE_CRYPTO is set from configure to determine if we are * compiled with any crypto support. */ #define MONGOC_ENABLE_CRYPTO 1 #if MONGOC_ENABLE_CRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO #endif /* * Use system crypto profile */ #define MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE 0 #if MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE != 1 # undef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE #endif /* * Use ASN1_STRING_get0_data () rather than the deprecated ASN1_STRING_data */ #define MONGOC_HAVE_ASN1_STRING_GET0_DATA 0 #if MONGOC_HAVE_ASN1_STRING_GET0_DATA != 1 # undef MONGOC_HAVE_ASN1_STRING_GET0_DATA #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_ENABLE_SASL_CYRUS is set from configure to determine if we are * compiled with Cyrus SASL support. */ #define MONGOC_ENABLE_SASL_CYRUS 1 #if MONGOC_ENABLE_SASL_CYRUS != 1 # undef MONGOC_ENABLE_SASL_CYRUS #endif /* * MONGOC_ENABLE_SASL_SSPI is set from configure to determine if we are * compiled with SSPI support. */ #define MONGOC_ENABLE_SASL_SSPI 0 #if MONGOC_ENABLE_SASL_SSPI != 1 # undef MONGOC_ENABLE_SASL_SSPI #endif /* * MONGOC_ENABLE_SASL_GSSAPI is set from configure to determine if we are * compiled with GSSAPI support. */ #define MONGOC_ENABLE_SASL_GSSAPI 0 #if MONGOC_ENABLE_SASL_GSSAPI != 1 # undef MONGOC_ENABLE_SASL_GSSAPI #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 /* * Disable automatic calls to mongoc_init() and mongoc_cleanup() * before main() is called, and after exit() (respectively). */ #define MONGOC_NO_AUTOMATIC_GLOBALS 1 #if MONGOC_NO_AUTOMATIC_GLOBALS != 1 # undef MONGOC_NO_AUTOMATIC_GLOBALS #endif /* * MONGOC_HAVE_SOCKLEN is set from configure to determine if we * need to emulate the type. */ #define MONGOC_HAVE_SOCKLEN 1 #if MONGOC_HAVE_SOCKLEN != 1 # undef MONGOC_HAVE_SOCKLEN #endif /* * Set from configure, see * https://curl.haxx.se/mail/lib-2009-04/0287.html */ #define MONGOC_SOCKET_ARG2 struct sockaddr #define MONGOC_SOCKET_ARG3 socklen_t /* * Enable wire protocol compression negotiation * */ #define MONGOC_ENABLE_COMPRESSION 0 #if MONGOC_ENABLE_COMPRESSION != 1 # undef MONGOC_ENABLE_COMPRESSION #endif /* * Set if we have snappy compression support * */ #define MONGOC_ENABLE_COMPRESSION_SNAPPY 0 #if MONGOC_ENABLE_COMPRESSION_SNAPPY != 1 # undef MONGOC_ENABLE_COMPRESSION_SNAPPY #endif /* * Set if we have zlib compression support * */ #define MONGOC_ENABLE_COMPRESSION_ZLIB 0 #if MONGOC_ENABLE_COMPRESSION_ZLIB != 1 # undef MONGOC_ENABLE_COMPRESSION_ZLIB #endif /* * NOTICE: * If you're about to update this file and add a config flag, make sure to * update: * o The bitfield in mongoc-handshake-private.h * o _get_config_bitfield() in mongoc-handshake.c * o examples/parse_handshake_cfg.py */ #endif /* MONGOC_CONFIG_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-config.h.in0000664000175000017500000001607413210321137023121 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_USER_SET_CFLAGS is set from config based on what compiler flags were * used to compile mongoc */ #define MONGOC_USER_SET_CFLAGS "@MONGOC_USER_SET_CFLAGS@" #define MONGOC_USER_SET_LDFLAGS "@MONGOC_USER_SET_LDFLAGS@" /* MONGOC_CC is used to determine what C compiler was used to compile mongoc */ #define MONGOC_CC "@MONGOC_CC@" /* * MONGOC_ENABLE_SSL_SECURE_CHANNEL is set from configure to determine if we are * compiled with Native SSL support on Windows */ #define MONGOC_ENABLE_SSL_SECURE_CHANNEL @MONGOC_ENABLE_SSL_SECURE_CHANNEL@ #if MONGOC_ENABLE_SSL_SECURE_CHANNEL != 1 # undef MONGOC_ENABLE_SSL_SECURE_CHANNEL #endif /* * MONGOC_ENABLE_CRYPTO_CNG is set from configure to determine if we are * compiled with Native Crypto support on Windows */ #define MONGOC_ENABLE_CRYPTO_CNG @MONGOC_ENABLE_CRYPTO_CNG@ #if MONGOC_ENABLE_CRYPTO_CNG != 1 # undef MONGOC_ENABLE_CRYPTO_CNG #endif /* * MONGOC_ENABLE_SSL_SECURE_TRANSPORT is set from configure to determine if we are * compiled with Native SSL support on Darwin */ #define MONGOC_ENABLE_SSL_SECURE_TRANSPORT @MONGOC_ENABLE_SSL_SECURE_TRANSPORT@ #if MONGOC_ENABLE_SSL_SECURE_TRANSPORT != 1 # undef MONGOC_ENABLE_SSL_SECURE_TRANSPORT #endif /* * MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO is set from configure to determine if we are * compiled with Native Crypto support on Darwin */ #define MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO @MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO@ #if MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO #endif /* * MONGOC_ENABLE_SSL_LIBRESSL is set from configure to determine if we are * compiled with LibreSSL support. */ #define MONGOC_ENABLE_SSL_LIBRESSL @MONGOC_ENABLE_SSL_LIBRESSL@ #if MONGOC_ENABLE_SSL_LIBRESSL != 1 # undef MONGOC_ENABLE_SSL_LIBRESSL #endif /* * MONGOC_ENABLE_SSL_OPENSSL is set from configure to determine if we are * compiled with OpenSSL support. */ #define MONGOC_ENABLE_SSL_OPENSSL @MONGOC_ENABLE_SSL_OPENSSL@ #if MONGOC_ENABLE_SSL_OPENSSL != 1 # undef MONGOC_ENABLE_SSL_OPENSSL #endif /* * MONGOC_ENABLE_CRYPTO_LIBCRYPTO is set from configure to determine if we are * compiled with OpenSSL support. */ #define MONGOC_ENABLE_CRYPTO_LIBCRYPTO @MONGOC_ENABLE_CRYPTO_LIBCRYPTO@ #if MONGOC_ENABLE_CRYPTO_LIBCRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO_LIBCRYPTO #endif /* * MONGOC_ENABLE_SSL is set from configure to determine if we are * compiled with any SSL support. */ #define MONGOC_ENABLE_SSL @MONGOC_ENABLE_SSL@ #if MONGOC_ENABLE_SSL != 1 # undef MONGOC_ENABLE_SSL #endif /* * MONGOC_ENABLE_CRYPTO is set from configure to determine if we are * compiled with any crypto support. */ #define MONGOC_ENABLE_CRYPTO @MONGOC_ENABLE_CRYPTO@ #if MONGOC_ENABLE_CRYPTO != 1 # undef MONGOC_ENABLE_CRYPTO #endif /* * Use system crypto profile */ #define MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE @MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE@ #if MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE != 1 # undef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE #endif /* * Use ASN1_STRING_get0_data () rather than the deprecated ASN1_STRING_data */ #define MONGOC_HAVE_ASN1_STRING_GET0_DATA @MONGOC_HAVE_ASN1_STRING_GET0_DATA@ #if MONGOC_HAVE_ASN1_STRING_GET0_DATA != 1 # undef MONGOC_HAVE_ASN1_STRING_GET0_DATA #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_ENABLE_SASL_CYRUS is set from configure to determine if we are * compiled with Cyrus SASL support. */ #define MONGOC_ENABLE_SASL_CYRUS @MONGOC_ENABLE_SASL_CYRUS@ #if MONGOC_ENABLE_SASL_CYRUS != 1 # undef MONGOC_ENABLE_SASL_CYRUS #endif /* * MONGOC_ENABLE_SASL_SSPI is set from configure to determine if we are * compiled with SSPI support. */ #define MONGOC_ENABLE_SASL_SSPI @MONGOC_ENABLE_SASL_SSPI@ #if MONGOC_ENABLE_SASL_SSPI != 1 # undef MONGOC_ENABLE_SASL_SSPI #endif /* * MONGOC_ENABLE_SASL_GSSAPI is set from configure to determine if we are * compiled with GSSAPI support. */ #define MONGOC_ENABLE_SASL_GSSAPI @MONGOC_ENABLE_SASL_GSSAPI@ #if MONGOC_ENABLE_SASL_GSSAPI != 1 # undef MONGOC_ENABLE_SASL_GSSAPI #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 /* * Disable automatic calls to mongoc_init() and mongoc_cleanup() * before main() is called, and after exit() (respectively). */ #define MONGOC_NO_AUTOMATIC_GLOBALS @MONGOC_NO_AUTOMATIC_GLOBALS@ #if MONGOC_NO_AUTOMATIC_GLOBALS != 1 # undef MONGOC_NO_AUTOMATIC_GLOBALS #endif /* * MONGOC_HAVE_SOCKLEN is set from configure to determine if we * need to emulate the type. */ #define MONGOC_HAVE_SOCKLEN @MONGOC_HAVE_SOCKLEN@ #if MONGOC_HAVE_SOCKLEN != 1 # undef MONGOC_HAVE_SOCKLEN #endif /* * Set from configure, see * https://curl.haxx.se/mail/lib-2009-04/0287.html */ #define MONGOC_SOCKET_ARG2 @MONGOC_SOCKET_ARG2@ #define MONGOC_SOCKET_ARG3 @MONGOC_SOCKET_ARG3@ /* * Enable wire protocol compression negotiation * */ #define MONGOC_ENABLE_COMPRESSION @MONGOC_ENABLE_COMPRESSION@ #if MONGOC_ENABLE_COMPRESSION != 1 # undef MONGOC_ENABLE_COMPRESSION #endif /* * Set if we have snappy compression support * */ #define MONGOC_ENABLE_COMPRESSION_SNAPPY @MONGOC_ENABLE_COMPRESSION_SNAPPY@ #if MONGOC_ENABLE_COMPRESSION_SNAPPY != 1 # undef MONGOC_ENABLE_COMPRESSION_SNAPPY #endif /* * Set if we have zlib compression support * */ #define MONGOC_ENABLE_COMPRESSION_ZLIB @MONGOC_ENABLE_COMPRESSION_ZLIB@ #if MONGOC_ENABLE_COMPRESSION_ZLIB != 1 # undef MONGOC_ENABLE_COMPRESSION_ZLIB #endif /* * NOTICE: * If you're about to update this file and add a config flag, make sure to * update: * o The bitfield in mongoc-handshake-private.h * o _get_config_bitfield() in mongoc-handshake.c * o examples/parse_handshake_cfg.py */ #endif /* MONGOC_CONFIG_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-counters-private.h0000664000175000017500000001161713210321137024557 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_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 #elif defined(__hpux__) #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(__hpux__) struct pst_dynamic psd; if (pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1) { return psd.psd_max_proc_cnt; } return 1; #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, rcx; __asm__ volatile("rdtscp\n" : "=a"(rax), "=d"(rdx), "=c"(rcx) : :); unsigned node_id, core_id; // node_id = (rcx & 0xFFF000)>>12; // node_id is unused core_id = rcx & 0xFFF; return core_id; } #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) \ { \ (void) _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.3.4/src/libmongoc/src/mongoc/mongoc-counters.c0000664000175000017500000001673713210321137023112 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 #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 skip_shm; } pid = getpid (); bson_snprintf (name, sizeof name, "/mongoc-%u", pid); #ifndef O_NOFOLLOW #define O_NOFOLLOW 0 #endif if (-1 == (fd = shm_open (name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR | O_NOFOLLOW))) { goto fail_noclean; } /* * 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 fail_cleanup; } mem = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { goto fail_cleanup; } close (fd); memset (mem, 0, size); return mem; fail_cleanup: shm_unlink (name); close (fd); fail_noclean: MONGOC_WARNING ("Falling back to malloc for counters."); skip_shm: #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.3.4/src/libmongoc/src/mongoc/mongoc-counters.defs0000664000175000017500000001102413210321137023571 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(op_egress_compressed, "Operations", "Egress Compressed", "The number of sent compressed operations.") COUNTER(op_ingress_compressed, "Operations", "Ingress Compressed", "The number of received compressed 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.3.4/src/libmongoc/src/mongoc/mongoc-crypto-cng-private.h0000664000175000017500000000265013210321137024777 0ustar jmikolajmikola/* * Copyright 2016 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_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_CRYPTO_CNG #ifndef MONGOC_CRYPTO_CNG_PRIVATE_H #define MONGOC_CRYPTO_CNG_PRIVATE_H #include "mongoc-config.h" BSON_BEGIN_DECLS void mongoc_crypto_cng_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */); bool mongoc_crypto_cng_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */); BSON_END_DECLS #endif /* MONGOC_CRYPTO_CNG_PRIVATE_H */ #endif /* MONGOC_ENABLE_CRYPTO_CNG */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto-cng.c0000664000175000017500000001101113210321137023311 0ustar jmikolajmikola/* Copyright 2016 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_CRYPTO_CNG #include "mongoc-crypto-private.h" #include "mongoc-crypto-cng-private.h" #include "mongoc-log.h" #include #include #include #define NT_SUCCESS(Status) (((NTSTATUS) (Status)) >= 0) #define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) bool _mongoc_crypto_cng_hmac_or_hash (BCRYPT_ALG_HANDLE algorithm, void *key, size_t key_length, void *data, size_t data_length, void *mac_out) { char *hash_object_buffer = 0; ULONG hash_object_length = 0; BCRYPT_HASH_HANDLE hash = 0; ULONG mac_length = 0; NTSTATUS status = STATUS_UNSUCCESSFUL; bool retval = false; ULONG noop = 0; status = BCryptGetProperty (algorithm, BCRYPT_OBJECT_LENGTH, (char *) &hash_object_length, sizeof hash_object_length, &noop, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptGetProperty(): OBJECT_LENGTH %x", status); return false; } status = BCryptGetProperty (algorithm, BCRYPT_HASH_LENGTH, (char *) &mac_length, sizeof mac_length, &noop, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptGetProperty(): HASH_LENGTH %x", status); return false; } hash_object_buffer = bson_malloc (hash_object_length); status = BCryptCreateHash (algorithm, &hash, hash_object_buffer, hash_object_length, key, (ULONG) key_length, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptCreateHash(): %x", status); goto cleanup; } status = BCryptHashData (hash, data, (ULONG) data_length, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptHashData(): %x", status); goto cleanup; } status = BCryptFinishHash (hash, mac_out, mac_length, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptFinishHash(): %x", status); goto cleanup; } retval = true; cleanup: if (hash) { (void) BCryptDestroyHash (hash); } bson_free (hash_object_buffer); return retval; } void mongoc_crypto_cng_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */) { static BCRYPT_ALG_HANDLE algorithm = 0; NTSTATUS status = STATUS_UNSUCCESSFUL; if (!algorithm) { status = BCryptOpenAlgorithmProvider ( &algorithm, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %x", status); return; } } _mongoc_crypto_cng_hmac_or_hash (algorithm, key, key_len, d, n, md); } bool mongoc_crypto_cng_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */) { static BCRYPT_ALG_HANDLE algorithm = 0; NTSTATUS status = STATUS_UNSUCCESSFUL; if (!algorithm) { status = BCryptOpenAlgorithmProvider ( &algorithm, BCRYPT_SHA1_ALGORITHM, NULL, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %x", status); return false; } } return _mongoc_crypto_cng_hmac_or_hash ( algorithm, NULL, 0, input, input_len, output); } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto-cng.h0000664000175000017500000000271213210321137023326 0ustar jmikolajmikola/* * Copyright 2016 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_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_CRYPTO_CNG #ifndef MONGOC_CRYPTO_CNG_H #define MONGOC_CRYPTO_CNG_H #include "mongoc-macros.h" #include "mongoc-config.h" BSON_BEGIN_DECLS MONGOC_EXPORT (void) mongoc_crypto_cng_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */); MONGOC_EXPORT (bool) mongoc_crypto_cng_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */); BSON_END_DECLS #endif /* MONGOC_CRYPTO_CNG_H */ #endif /* MONGOC_ENABLE_CRYPTO_CNG */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto-private.h0000664000175000017500000000307513210321137027040 0ustar jmikolajmikola/* * Copyright 2016 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_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO #ifndef MONGOC_CRYPTO_COMMON_CRYPTO_PRIVATE_H #define MONGOC_CRYPTO_COMMON_CRYPTO_PRIVATE_H #include "mongoc-config.h" BSON_BEGIN_DECLS void mongoc_crypto_common_crypto_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */); bool mongoc_crypto_common_crypto_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */); BSON_END_DECLS #endif /* MONGOC_CRYPTO_COMMON_CRYPTO_PRIVATE_H */ #endif /* MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto-common-crypto.c0000664000175000017500000000313113210321137025354 0ustar jmikolajmikola/* Copyright 2016 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" #include "mongoc-crypto-private.h" #ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO #include "mongoc-crypto-common-crypto-private.h" #include #include void mongoc_crypto_common_crypto_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */) { /* U1 = HMAC(input, salt + 0001) */ CCHmac (kCCHmacAlgSHA1, key, key_len, d, n, md); } bool mongoc_crypto_common_crypto_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */) { if (CC_SHA1 (input, input_len, output)) { return true; } return false; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto-openssl-private.h0000664000175000017500000000303213210321137025706 0ustar jmikolajmikola/* * Copyright 2016 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_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-config.h" #include #ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO #ifndef MONGOC_CRYPTO_OPENSSL_PRIVATE_H #define MONGOC_CRYPTO_OPENSSL_PRIVATE_H #include "mongoc-crypto-private.h" BSON_BEGIN_DECLS void mongoc_crypto_openssl_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */); bool mongoc_crypto_openssl_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */); BSON_END_DECLS #endif /* MONGOC_CRYPTO_OPENSSL_PRIVATE_H */ #endif /* MONGOC_ENABLE_CRYPTO_LIBCRYPTO */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto-openssl.c0000664000175000017500000000412613210321137024236 0ustar jmikolajmikola/* * Copyright 2016 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" #include #ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO #include "mongoc-crypto-openssl-private.h" #include "mongoc-crypto-private.h" #include #include #include void mongoc_crypto_openssl_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */) { /* U1 = HMAC(input, salt + 0001) */ HMAC (EVP_sha1 (), key, key_len, d, n, md, NULL); } #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) EVP_MD_CTX * EVP_MD_CTX_new (void) { return bson_malloc0 (sizeof (EVP_MD_CTX)); } void EVP_MD_CTX_free (EVP_MD_CTX *ctx) { EVP_MD_CTX_cleanup (ctx); bson_free (ctx); } #endif bool mongoc_crypto_openssl_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */) { EVP_MD_CTX *digest_ctxp = EVP_MD_CTX_new (); bool rval = false; if (1 != EVP_DigestInit_ex (digest_ctxp, EVP_sha1 (), NULL)) { goto cleanup; } if (1 != EVP_DigestUpdate (digest_ctxp, input, input_len)) { goto cleanup; } rval = (1 == EVP_DigestFinal_ex (digest_ctxp, output, NULL)); cleanup: EVP_MD_CTX_free (digest_ctxp); return rval; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto-private.h0000664000175000017500000000365313210321137024236 0ustar jmikolajmikola/* * Copyright 2016 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_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-config.h" #include #ifdef MONGOC_ENABLE_CRYPTO #ifndef MONGOC_CRYPTO_PRIVATE_H #define MONGOC_CRYPTO_PRIVATE_H BSON_BEGIN_DECLS typedef struct _mongoc_crypto_t mongoc_crypto_t; struct _mongoc_crypto_t { void (*hmac_sha1) (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */); bool (*sha1) (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */); }; void mongoc_crypto_init (mongoc_crypto_t *crypto); void mongoc_crypto_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */); bool mongoc_crypto_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */); BSON_END_DECLS #endif /* MONGOC_CRYPTO_PRIVATE_H */ #endif /* MONGOC_ENABLE_CRYPTO */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-crypto.c0000664000175000017500000000405713210321137022560 0ustar jmikolajmikola/* Copyright 2016 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_CRYPTO #include #include "mongoc-log.h" #include "mongoc-crypto-private.h" #if defined(MONGOC_ENABLE_CRYPTO_LIBCRYPTO) #include "mongoc-crypto-openssl-private.h" #elif defined(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO) #include "mongoc-crypto-common-crypto-private.h" #elif defined(MONGOC_ENABLE_CRYPTO_CNG) #include "mongoc-crypto-cng-private.h" #endif void mongoc_crypto_init (mongoc_crypto_t *crypto) { #ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO crypto->hmac_sha1 = mongoc_crypto_openssl_hmac_sha1; crypto->sha1 = mongoc_crypto_openssl_sha1; #elif defined(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO) crypto->hmac_sha1 = mongoc_crypto_common_crypto_hmac_sha1; crypto->sha1 = mongoc_crypto_common_crypto_sha1; #elif defined(MONGOC_ENABLE_CRYPTO_CNG) crypto->hmac_sha1 = mongoc_crypto_cng_hmac_sha1; crypto->sha1 = mongoc_crypto_cng_sha1; #endif } void mongoc_crypto_hmac_sha1 (mongoc_crypto_t *crypto, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md /* OUT */) { crypto->hmac_sha1 (crypto, key, key_len, d, n, md); } bool mongoc_crypto_sha1 (mongoc_crypto_t *crypto, const unsigned char *input, const size_t input_len, unsigned char *output /* OUT */) { return crypto->sha1 (crypto, input, input_len, output); } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cursor-array-private.h0000664000175000017500000000226513210321137025345 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_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.3.4/src/libmongoc/src/mongoc/mongoc-cursor-array.c0000664000175000017500000001205613210321137023667 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-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cursor-array" typedef struct { bson_t array; bool has_array; bool has_synthetic_bson; bson_iter_t iter; bson_t bson; /* current 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->has_array = false; arr->has_synthetic_bson = false; 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_array) { bson_destroy (&arr->array); } 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) { 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->filter, &arr->array) && bson_iter_init_find (&iter, &arr->array, arr->field_name) && BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &arr->iter)) { arr->has_array = true; return true; } return false; } static bool _mongoc_cursor_array_next (mongoc_cursor_t *cursor, const bson_t **bson) { bool ret = true; mongoc_cursor_array_t *arr; uint32_t document_len; const uint8_t *document; ENTRY; arr = (mongoc_cursor_array_t *) cursor->iface_data; *bson = NULL; if (!arr->has_array && !arr->has_synthetic_bson) { ret = _mongoc_cursor_array_prime (cursor); } if (ret) { ret = bson_iter_next (&arr->iter); } if (ret) { bson_iter_document (&arr->iter, &document_len, &document); bson_init_static (&arr->bson, document, 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->filter, 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 || arr->has_synthetic_bson) { memcpy (&iter, &arr->iter, sizeof iter); ret = bson_iter_next (&iter); } else { ret = true; } RETURN (ret); } static bool _mongoc_cursor_array_error_document (mongoc_cursor_t *cursor, bson_error_t *error, const bson_t **doc) { mongoc_cursor_array_t *arr; ENTRY; arr = (mongoc_cursor_array_t *) cursor->iface_data; if (arr->has_synthetic_bson) { if (doc) { *doc = NULL; } return false; } return _mongoc_cursor_error_document (cursor, error, doc); } 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_document, }; void _mongoc_cursor_array_init (mongoc_cursor_t *cursor, const bson_t *command, const char *field_name) { ENTRY; if (command) { bson_destroy (&cursor->filter); bson_copy_to (command, &cursor->filter); } 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_synthetic_bson = true; bson_iter_init (&arr->iter, &arr->bson); EXIT; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cursor-cursorid-private.h0000664000175000017500000000321213210321137026052 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_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-cursor-private.h" BSON_BEGIN_DECLS typedef struct { bson_t array; bool in_batch; bool in_reader; bson_iter_t batch_iter; bson_t current_doc; } mongoc_cursor_cursorid_t; bool _mongoc_cursor_cursorid_start_batch (mongoc_cursor_t *cursor); 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); bool _mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor, bson_t *command); void _mongoc_cursor_cursorid_init_with_reply (mongoc_cursor_t *cursor, bson_t *reply, uint32_t server_id); BSON_END_DECLS #endif /* MONGOC_CURSOR_CURSORID_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cursor-cursorid.c0000664000175000017500000002407513210321137024407 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-private.h" #include "mongoc-error.h" #include "mongoc-util-private.h" #include "mongoc-client-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); bson_init (&cid->array); cid->in_batch = false; cid->in_reader = false; RETURN (cid); } static void _mongoc_cursor_cursorid_destroy (mongoc_cursor_t *cursor) { mongoc_cursor_cursorid_t *cid; ENTRY; cid = (mongoc_cursor_cursorid_t *) cursor->iface_data; BSON_ASSERT (cid); bson_destroy (&cid->array); bson_free (cid); _mongoc_cursor_destroy (cursor); EXIT; } /* * Start iterating the reply to an "aggregate", "find", "getMore" etc. command: * * {cursor: {id: 1234, ns: "db.collection", firstBatch: [...]}} */ bool _mongoc_cursor_cursorid_start_batch (mongoc_cursor_t *cursor) { mongoc_cursor_cursorid_t *cid; bson_iter_t iter; bson_iter_t child; const char *ns; uint32_t nslen; cid = (mongoc_cursor_cursorid_t *) cursor->iface_data; BSON_ASSERT (cid); if (bson_iter_init_find (&iter, &cid->array, "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, &nslen); _mongoc_set_cursor_ns (cursor, ns, nslen); } 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 cid->in_batch; } static bool _mongoc_cursor_cursorid_refresh_from_command (mongoc_cursor_t *cursor, const bson_t *command) { mongoc_cursor_cursorid_t *cid; ENTRY; cid = (mongoc_cursor_cursorid_t *) cursor->iface_data; BSON_ASSERT (cid); bson_destroy (&cid->array); /* 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, &cid->array) && _mongoc_cursor_cursorid_start_batch (cursor)) { RETURN (true); } bson_destroy (&cursor->error_doc); bson_copy_to (&cid->array, &cursor->error_doc); 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); /* bson_iter_next guarantees valid BSON, so this must succeed */ bson_init_static (&cid->current_doc, data, data_len); *bson = &cid->current_doc; cursor->end_of_event = false; } else { cursor->end_of_event = true; } } bool _mongoc_cursor_cursorid_prime (mongoc_cursor_t *cursor) { cursor->sent = true; cursor->operation_id = ++cursor->client->cluster.operation_id; return _mongoc_cursor_cursorid_refresh_from_command (cursor, &cursor->filter); } bool _mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor, bson_t *command) { const char *collection; int collection_len; int64_t batch_size; bool await_data; int32_t max_await_time_ms; ENTRY; _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); batch_size = mongoc_cursor_get_batch_size (cursor); /* See find, getMore, and killCursors Spec for batchSize rules */ if (batch_size) { bson_append_int64 (command, MONGOC_CURSOR_BATCH_SIZE, MONGOC_CURSOR_BATCH_SIZE_LEN, abs (_mongoc_n_return (cursor))); } /* 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." */ await_data = _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_TAILABLE) && _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_AWAIT_DATA); if (await_data) { max_await_time_ms = (int32_t) mongoc_cursor_get_max_await_time_ms (cursor); if (max_await_time_ms) { bson_append_int32 (command, MONGOC_CURSOR_MAX_TIME_MS, MONGOC_CURSOR_MAX_TIME_MS_LEN, max_await_time_ms); } } RETURN (true); } 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_getmore_command (cursor, server_stream)) { if (!_mongoc_cursor_prepare_getmore_command (cursor, &command)) { mongoc_server_stream_cleanup (server_stream); RETURN (false); } 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: /* Two paths: * - Mongo 3.2+, sent "getMore" cmd, we're reading reply's "nextBatch" array * - Mongo 2.6 to 3, after "aggregate" or similar command we sent OP_GETMORE, * we're reading the raw reply */ 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: if (!*bson && mongoc_cursor_get_id (cursor) == 0) { cursor->done = 1; } RETURN (*bson != NULL); } 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->filter); 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->filter); bson_copy_to (command, &cursor->filter); cursor->iface_data = _mongoc_cursor_cursorid_new (); memcpy (&cursor->iface, &gMongocCursorCursorid, sizeof (mongoc_cursor_interface_t)); EXIT; } void _mongoc_cursor_cursorid_init_with_reply (mongoc_cursor_t *cursor, bson_t *reply, uint32_t server_id) { mongoc_cursor_cursorid_t *cid; cursor->sent = true; cursor->server_id = server_id; cid = (mongoc_cursor_cursorid_t *) cursor->iface_data; BSON_ASSERT (cid); bson_destroy (&cid->array); if (!bson_steal (&cid->array, reply)) { bson_steal (&cid->array, bson_copy (reply)); } if (!_mongoc_cursor_cursorid_start_batch (cursor)) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Couldn't parse cursor document"); } } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cursor-private.h0000664000175000017500000001603513210321137024231 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_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_document) (mongoc_cursor_t *cursor, bson_error_t *error, const bson_t **doc); void (*get_host) (mongoc_cursor_t *cursor, mongoc_host_list_t *host); }; #define MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS "allowPartialResults" #define MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS_LEN 19 #define MONGOC_CURSOR_AWAIT_DATA "awaitData" #define MONGOC_CURSOR_AWAIT_DATA_LEN 9 #define MONGOC_CURSOR_BATCH_SIZE "batchSize" #define MONGOC_CURSOR_BATCH_SIZE_LEN 9 #define MONGOC_CURSOR_COLLATION "collation" #define MONGOC_CURSOR_COLLATION_LEN 9 #define MONGOC_CURSOR_COMMENT "comment" #define MONGOC_CURSOR_COMMENT_LEN 7 #define MONGOC_CURSOR_EXHAUST "exhaust" #define MONGOC_CURSOR_EXHAUST_LEN 7 #define MONGOC_CURSOR_FILTER "filter" #define MONGOC_CURSOR_FILTER_LEN 6 #define MONGOC_CURSOR_FIND "find" #define MONGOC_CURSOR_FIND_LEN 4 #define MONGOC_CURSOR_HINT "hint" #define MONGOC_CURSOR_HINT_LEN 4 #define MONGOC_CURSOR_LIMIT "limit" #define MONGOC_CURSOR_LIMIT_LEN 5 #define MONGOC_CURSOR_MAX "max" #define MONGOC_CURSOR_MAX_LEN 3 #define MONGOC_CURSOR_MAX_AWAIT_TIME_MS "maxAwaitTimeMS" #define MONGOC_CURSOR_MAX_AWAIT_TIME_MS_LEN 14 #define MONGOC_CURSOR_MAX_SCAN "maxScan" #define MONGOC_CURSOR_MAX_SCAN_LEN 7 #define MONGOC_CURSOR_MAX_TIME_MS "maxTimeMS" #define MONGOC_CURSOR_MAX_TIME_MS_LEN 9 #define MONGOC_CURSOR_MIN "min" #define MONGOC_CURSOR_MIN_LEN 3 #define MONGOC_CURSOR_NO_CURSOR_TIMEOUT "noCursorTimeout" #define MONGOC_CURSOR_NO_CURSOR_TIMEOUT_LEN 15 #define MONGOC_CURSOR_OPLOG_REPLAY "oplogReplay" #define MONGOC_CURSOR_OPLOG_REPLAY_LEN 11 #define MONGOC_CURSOR_ORDERBY "orderby" #define MONGOC_CURSOR_ORDERBY_LEN 7 #define MONGOC_CURSOR_PROJECTION "projection" #define MONGOC_CURSOR_PROJECTION_LEN 10 #define MONGOC_CURSOR_QUERY "query" #define MONGOC_CURSOR_QUERY_LEN 5 #define MONGOC_CURSOR_READ_CONCERN "readConcern" #define MONGOC_CURSOR_READ_CONCERN_LEN 11 #define MONGOC_CURSOR_RETURN_KEY "returnKey" #define MONGOC_CURSOR_RETURN_KEY_LEN 9 #define MONGOC_CURSOR_SHOW_DISK_LOC "showDiskLoc" #define MONGOC_CURSOR_SHOW_DISK_LOC_LEN 11 #define MONGOC_CURSOR_SHOW_RECORD_ID "showRecordId" #define MONGOC_CURSOR_SHOW_RECORD_ID_LEN 12 #define MONGOC_CURSOR_SINGLE_BATCH "singleBatch" #define MONGOC_CURSOR_SINGLE_BATCH_LEN 11 #define MONGOC_CURSOR_SKIP "skip" #define MONGOC_CURSOR_SKIP_LEN 4 #define MONGOC_CURSOR_SNAPSHOT "snapshot" #define MONGOC_CURSOR_SNAPSHOT_LEN 8 #define MONGOC_CURSOR_SORT "sort" #define MONGOC_CURSOR_SORT_LEN 4 #define MONGOC_CURSOR_TAILABLE "tailable" #define MONGOC_CURSOR_TAILABLE_LEN 8 struct _mongoc_cursor_t { mongoc_client_t *client; uint32_t server_id; bool server_id_set; bool slave_ok; 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 filter; bson_t opts; mongoc_read_concern_t *read_concern; mongoc_read_prefs_t *read_prefs; mongoc_write_concern_t *write_concern; uint32_t count; char ns[140]; uint32_t nslen; uint32_t dblen; bson_error_t error; bson_t error_doc; /* for OP_QUERY and OP_GETMORE replies*/ mongoc_rpc_t rpc; mongoc_buffer_t buffer; bson_reader_t *reader; const bson_t *current; mongoc_cursor_interface_t iface; void *iface_data; int64_t operation_id; }; int32_t _mongoc_n_return (mongoc_cursor_t *cursor); void _mongoc_set_cursor_ns (mongoc_cursor_t *cursor, const char *ns, uint32_t nslen); bool _mongoc_cursor_get_opt_bool (const mongoc_cursor_t *cursor, const char *option); mongoc_cursor_t * _mongoc_cursor_new_with_opts (mongoc_client_t *client, const char *db_and_collection, bool is_command, const bson_t *filter, const bson_t *opts, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern); 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); bool _use_getmore_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, bson_t *reply); bool _mongoc_cursor_more (mongoc_cursor_t *cursor); bool _mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson); bool _mongoc_cursor_error_document (mongoc_cursor_t *cursor, bson_error_t *error, const bson_t **doc); void _mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host); BSON_END_DECLS #endif /* MONGOC_CURSOR_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cursor-transform-private.h0000664000175000017500000000331213210321137026234 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_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.3.4/src/libmongoc/src/mongoc/mongoc-cursor-transform.c0000664000175000017500000001011413210321137024555 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-private.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.3.4/src/libmongoc/src/mongoc/mongoc-cursor.c0000664000175000017500000017456013210321137022564 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-private.h" #include "mongoc-cursor-cursorid-private.h" #include "mongoc-read-concern-private.h" #include "mongoc-util-private.h" #include "mongoc-write-concern-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cursor" #define CURSOR_FAILED(cursor_) ((cursor_)->error.domain != 0) static bool _translate_query_opt (const char *query_field, const char **cmd_field, int *len); static const bson_t * _mongoc_cursor_op_query (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream); static bool _mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor, bson_t *command, mongoc_server_stream_t *server_stream); static const bson_t * _mongoc_cursor_find_command (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream); static bool _mongoc_cursor_set_opt_int64 (mongoc_cursor_t *cursor, const char *option, int64_t value) { bson_iter_t iter; if (bson_iter_init_find (&iter, &cursor->opts, option)) { if (!BSON_ITER_HOLDS_INT64 (&iter)) { return false; } bson_iter_overwrite_int64 (&iter, value); return true; } return BSON_APPEND_INT64 (&cursor->opts, option, value); } static int64_t _mongoc_cursor_get_opt_int64 (const mongoc_cursor_t *cursor, const char *option, int64_t default_value) { bson_iter_t iter; if (bson_iter_init_find (&iter, &cursor->opts, option)) { return bson_iter_as_int64 (&iter); } return default_value; } static bool _mongoc_cursor_set_opt_bool (mongoc_cursor_t *cursor, const char *option, bool value) { bson_iter_t iter; if (bson_iter_init_find (&iter, &cursor->opts, option)) { if (!BSON_ITER_HOLDS_BOOL (&iter)) { return false; } bson_iter_overwrite_bool (&iter, value); return true; } return BSON_APPEND_BOOL (&cursor->opts, option, value); } bool _mongoc_cursor_get_opt_bool (const mongoc_cursor_t *cursor, const char *option) { bson_iter_t iter; if (bson_iter_init_find (&iter, &cursor->opts, option)) { return bson_iter_as_bool (&iter); } return false; } int32_t _mongoc_n_return (mongoc_cursor_t *cursor) { int64_t limit; int64_t batch_size; int64_t n_return; if (cursor->is_command) { /* commands always have n_return of 1 */ return 1; } limit = mongoc_cursor_get_limit (cursor); batch_size = mongoc_cursor_get_batch_size (cursor); if (limit < 0) { n_return = limit; } else if (limit) { int64_t remaining = limit - cursor->count; BSON_ASSERT (remaining > 0); if (batch_size) { n_return = BSON_MIN (batch_size, remaining); } else { /* batch_size 0 means accept the default */ n_return = remaining; } } else { n_return = batch_size; } if (n_return < INT32_MIN) { return INT32_MIN; } else if (n_return > INT32_MAX) { return INT32_MAX; } else { return (int32_t) n_return; } } void _mongoc_set_cursor_ns (mongoc_cursor_t *cursor, const char *ns, uint32_t nslen) { const char *dot; bson_strncpy (cursor->ns, ns, sizeof cursor->ns); cursor->nslen = BSON_MIN (nslen, sizeof cursor->ns); dot = strstr (cursor->ns, "."); if (dot) { cursor->dblen = (uint32_t) (dot - cursor->ns); } else { /* a database name with no collection name */ cursor->dblen = cursor->nslen; } } /* return first key beginning with $, or NULL. precondition: bson is valid. */ static const char * _first_dollar_field (const bson_t *bson) { bson_iter_t iter; const char *key; BSON_ASSERT (bson_iter_init (&iter, bson)); while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (key[0] == '$') { return key; } } return NULL; } #define MARK_FAILED(c) \ do { \ (c)->done = true; \ (c)->end_of_event = true; \ (c)->sent = true; \ } while (0) mongoc_cursor_t * _mongoc_cursor_new_with_opts (mongoc_client_t *client, const char *db_and_collection, bool is_command, const bson_t *filter, const bson_t *opts, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern) { mongoc_cursor_t *cursor; mongoc_topology_description_type_t td_type; uint32_t server_id; bson_error_t validate_err; const char *dollar_field; ENTRY; BSON_ASSERT (client); cursor = (mongoc_cursor_t *) bson_malloc0 (sizeof *cursor); cursor->client = client; cursor->is_command = is_command ? 1 : 0; bson_init (&cursor->filter); bson_init (&cursor->opts); bson_init (&cursor->error_doc); if (filter) { if (!bson_validate_with_error ( filter, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) { MARK_FAILED (cursor); bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Invalid filter: %s", validate_err.message); GOTO (finish); } bson_destroy (&cursor->filter); bson_copy_to (filter, &cursor->filter); } if (opts) { if (!bson_validate_with_error ( opts, BSON_VALIDATE_EMPTY_KEYS, &validate_err)) { MARK_FAILED (cursor); bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Invalid opts: %s", validate_err.message); GOTO (finish); } dollar_field = _first_dollar_field (opts); if (dollar_field) { MARK_FAILED (cursor); bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot use $-modifiers in opts: \"%s\"", dollar_field); GOTO (finish); } bson_copy_to_excluding_noinit (opts, &cursor->opts, "serverId", NULL); /* true if there's a valid serverId or no serverId, false on err */ if (!_mongoc_get_server_id_from_opts (opts, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, &server_id, &cursor->error)) { MARK_FAILED (cursor); GOTO (finish); } if (server_id) { mongoc_cursor_set_hint (cursor, server_id); } } cursor->read_prefs = read_prefs ? mongoc_read_prefs_copy (read_prefs) : mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor->read_concern = read_concern ? mongoc_read_concern_copy (read_concern) : mongoc_read_concern_new (); if (db_and_collection) { _mongoc_set_cursor_ns ( cursor, db_and_collection, (uint32_t) strlen (db_and_collection)); } if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) { if (_mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0)) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot specify both 'exhaust' and 'limit'."); MARK_FAILED (cursor); GOTO (finish); } td_type = _mongoc_topology_get_type (client->topology); if (td_type == MONGOC_TOPOLOGY_SHARDED) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot use exhaust cursor with sharded cluster."); MARK_FAILED (cursor); GOTO (finish); } } _mongoc_buffer_init (&cursor->buffer, NULL, 0, NULL, NULL); _mongoc_read_prefs_validate (read_prefs, &cursor->error); finish: mongoc_counter_cursors_active_inc (); RETURN (cursor); } 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) { bson_t filter; bool has_filter = false; bson_t opts = BSON_INITIALIZER; bool slave_ok = false; const char *key; bson_iter_t iter; const char *opt_key; int len; uint32_t data_len; const uint8_t *data; mongoc_cursor_t *cursor; bson_error_t error = {0}; ENTRY; BSON_ASSERT (client); if (query) { if (bson_has_field (query, "$query")) { /* like "{$query: {a: 1}, $orderby: {b: 1}, $otherModifier: true}" */ bson_iter_init (&iter, query); while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (key[0] != '$') { bson_set_error (&error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot mix $query with non-dollar field '%s'", key); GOTO (done); } if (!strcmp (key, "$query")) { /* set "filter" to the incoming document's "$query" */ bson_iter_document (&iter, &data_len, &data); bson_init_static (&filter, data, (size_t) data_len); has_filter = true; } else if (_translate_query_opt (key, &opt_key, &len)) { /* "$orderby" becomes "sort", etc., "$unknown" -> "unknown" */ bson_append_iter (&opts, opt_key, len, &iter); } else { /* strip leading "$" */ bson_append_iter (&opts, key + 1, -1, &iter); } } } } if (!bson_empty0 (fields)) { bson_append_document ( &opts, MONGOC_CURSOR_PROJECTION, MONGOC_CURSOR_PROJECTION_LEN, fields); } if (skip) { bson_append_int64 ( &opts, MONGOC_CURSOR_SKIP, MONGOC_CURSOR_SKIP_LEN, skip); } if (limit) { bson_append_int64 ( &opts, MONGOC_CURSOR_LIMIT, MONGOC_CURSOR_LIMIT_LEN, llabs (limit)); if (limit < 0) { bson_append_bool (&opts, MONGOC_CURSOR_SINGLE_BATCH, MONGOC_CURSOR_SINGLE_BATCH_LEN, true); } } if (batch_size) { bson_append_int64 (&opts, MONGOC_CURSOR_BATCH_SIZE, MONGOC_CURSOR_BATCH_SIZE_LEN, batch_size); } if (qflags & MONGOC_QUERY_SLAVE_OK) { slave_ok = true; } if (qflags & MONGOC_QUERY_TAILABLE_CURSOR) { bson_append_bool ( &opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true); } if (qflags & MONGOC_QUERY_OPLOG_REPLAY) { bson_append_bool (&opts, MONGOC_CURSOR_OPLOG_REPLAY, MONGOC_CURSOR_OPLOG_REPLAY_LEN, true); } if (qflags & MONGOC_QUERY_NO_CURSOR_TIMEOUT) { bson_append_bool (&opts, MONGOC_CURSOR_NO_CURSOR_TIMEOUT, MONGOC_CURSOR_NO_CURSOR_TIMEOUT_LEN, true); } if (qflags & MONGOC_QUERY_AWAIT_DATA) { bson_append_bool ( &opts, MONGOC_CURSOR_AWAIT_DATA, MONGOC_CURSOR_AWAIT_DATA_LEN, true); } if (qflags & MONGOC_QUERY_EXHAUST) { bson_append_bool ( &opts, MONGOC_CURSOR_EXHAUST, MONGOC_CURSOR_EXHAUST_LEN, true); } if (qflags & MONGOC_QUERY_PARTIAL) { bson_append_bool (&opts, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS_LEN, true); } done: if (error.domain != 0) { cursor = _mongoc_cursor_new_with_opts ( client, db_and_collection, is_command, NULL, NULL, NULL, NULL); MARK_FAILED (cursor); memcpy (&cursor->error, &error, sizeof (bson_error_t)); } else { cursor = _mongoc_cursor_new_with_opts (client, db_and_collection, is_command, has_filter ? &filter : query, &opts, read_prefs, read_concern); if (slave_ok) { cursor->slave_ok = true; } } if (has_filter) { bson_destroy (&filter); } bson_destroy (&opts); 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->server_id, false, NULL); } } else if (cursor->rpc.reply.cursor_id) { bson_strncpy (db, cursor->ns, cursor->dblen + 1); _mongoc_client_kill_cursor (cursor->client, cursor->server_id, cursor->rpc.reply.cursor_id, cursor->operation_id, db, cursor->ns + cursor->dblen + 1); } if (cursor->reader) { bson_reader_destroy (cursor->reader); cursor->reader = NULL; } _mongoc_buffer_destroy (&cursor->buffer); mongoc_read_prefs_destroy (cursor->read_prefs); mongoc_read_concern_destroy (cursor->read_concern); mongoc_write_concern_destroy (cursor->write_concern); bson_destroy (&cursor->filter); bson_destroy (&cursor->opts); bson_destroy (&cursor->error_doc); 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->server_id) { server_stream = mongoc_cluster_stream_for_server (&cursor->client->cluster, cursor->server_id, 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->server_id = 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 && !_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST); } bool _use_getmore_command (const mongoc_cursor_t *cursor, const mongoc_server_stream_t *server_stream) { return server_stream->sd->max_wire_version >= WIRE_VERSION_FIND_CMD && !_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_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, server_stream); } 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 bool _mongoc_cursor_monitor_legacy_query (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream, const char *cmd_name) { bson_t doc; mongoc_client_t *client; mongoc_apm_command_started_t event; char db[MONGOC_NAMESPACE_MAX]; ENTRY; client = cursor->client; if (!client->apm_callbacks.started) { /* successful */ RETURN (true); } bson_init (&doc); bson_strncpy (db, cursor->ns, cursor->dblen + 1); if (!cursor->is_command) { /* simulate a MongoDB 3.2+ "find" command */ if (!_mongoc_cursor_prepare_find_command (cursor, &doc, server_stream)) { /* cursor->error is set */ bson_destroy (&doc); RETURN (false); } } mongoc_apm_command_started_init (&event, cursor->is_command ? &cursor->filter : &doc, db, cmd_name, client->cluster.request_id, cursor->operation_id, &server_stream->sd->host, server_stream->sd->id, client->apm_context); client->apm_callbacks.started (&event); mongoc_apm_command_started_cleanup (&event); bson_destroy (&doc); RETURN (true); } /* append array of docs from current cursor batch */ static void _mongoc_cursor_append_docs_array (mongoc_cursor_t *cursor, bson_t *docs) { bool eof = false; char str[16]; const char *key; uint32_t i = 0; size_t keylen; const bson_t *doc; while ((doc = bson_reader_read (cursor->reader, &eof))) { keylen = bson_uint32_to_string (i, &key, str, sizeof str); bson_append_document (docs, key, (int) keylen, doc); } bson_reader_reset (cursor->reader); } static void _mongoc_cursor_monitor_succeeded (mongoc_cursor_t *cursor, int64_t duration, bool first_batch, mongoc_server_stream_t *stream, const char *cmd_name) { mongoc_apm_command_succeeded_t event; mongoc_client_t *client; bson_t reply; bson_t reply_cursor; ENTRY; client = cursor->client; if (!client->apm_callbacks.succeeded) { EXIT; } if (cursor->is_command) { /* cursor is from mongoc_client_command. we're in mongoc_cursor_next. */ if (!_mongoc_rpc_reply_get_first (&cursor->rpc.reply, &reply)) { MONGOC_ERROR ("_mongoc_cursor_monitor_succeeded can't parse reply"); EXIT; } } else { bson_t docs_array; /* fake reply to find/getMore command: * {ok: 1, cursor: {id: 17, ns: "...", first/nextBatch: [ ... docs ... ]}} */ bson_init (&docs_array); _mongoc_cursor_append_docs_array (cursor, &docs_array); bson_init (&reply); bson_append_int32 (&reply, "ok", 2, 1); bson_append_document_begin (&reply, "cursor", 6, &reply_cursor); bson_append_int64 (&reply_cursor, "id", 2, mongoc_cursor_get_id (cursor)); bson_append_utf8 (&reply_cursor, "ns", 2, cursor->ns, cursor->nslen); bson_append_array (&reply_cursor, first_batch ? "firstBatch" : "nextBatch", first_batch ? 10 : 9, &docs_array); bson_append_document_end (&reply, &reply_cursor); bson_destroy (&docs_array); } mongoc_apm_command_succeeded_init (&event, duration, &reply, cmd_name, client->cluster.request_id, cursor->operation_id, &stream->sd->host, stream->sd->id, client->apm_context); client->apm_callbacks.succeeded (&event); mongoc_apm_command_succeeded_cleanup (&event); bson_destroy (&reply); EXIT; } static void _mongoc_cursor_monitor_failed (mongoc_cursor_t *cursor, int64_t duration, mongoc_server_stream_t *stream, const char *cmd_name) { mongoc_apm_command_failed_t event; mongoc_client_t *client; ENTRY; client = cursor->client; if (!client->apm_callbacks.failed) { EXIT; } mongoc_apm_command_failed_init (&event, duration, cmd_name, &cursor->error, client->cluster.request_id, cursor->operation_id, &stream->sd->host, stream->sd->id, client->apm_context); client->apm_callbacks.failed (&event); mongoc_apm_command_failed_cleanup (&event); EXIT; } #define OPT_CHECK(_type) \ do { \ if (!BSON_ITER_HOLDS_##_type (&iter)) { \ bson_set_error (&cursor->error, \ MONGOC_ERROR_COMMAND, \ MONGOC_ERROR_COMMAND_INVALID_ARG, \ "invalid option %s, should be type %s", \ key, \ #_type); \ return NULL; \ } \ } while (false) #define OPT_CHECK_INT() \ do { \ if (!BSON_ITER_HOLDS_INT (&iter)) { \ bson_set_error (&cursor->error, \ MONGOC_ERROR_COMMAND, \ MONGOC_ERROR_COMMAND_INVALID_ARG, \ "invalid option %s, should be integer", \ key); \ return NULL; \ } \ } while (false) #define OPT_ERR(_msg) \ do { \ bson_set_error (&cursor->error, \ MONGOC_ERROR_COMMAND, \ MONGOC_ERROR_COMMAND_INVALID_ARG, \ _msg); \ return NULL; \ } while (false) #define OPT_BSON_ERR(_msg) \ do { \ bson_set_error ( \ &cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, _msg); \ return NULL; \ } while (false) #define OPT_FLAG(_flag) \ do { \ OPT_CHECK (BOOL); \ if (bson_iter_as_bool (&iter)) { \ *flags |= _flag; \ } \ } while (false) #define PUSH_DOLLAR_QUERY() \ do { \ if (!pushed_dollar_query) { \ pushed_dollar_query = true; \ bson_append_document (query, "$query", 6, &cursor->filter); \ } \ } while (false) #define OPT_SUBDOCUMENT(_opt_name, _legacy_name) \ do { \ OPT_CHECK (DOCUMENT); \ bson_iter_document (&iter, &len, &data); \ if (!bson_init_static (&subdocument, data, (size_t) len)) { \ OPT_BSON_ERR ("Invalid '" #_opt_name "' subdocument in 'opts'."); \ } \ BSON_APPEND_DOCUMENT (query, "$" #_legacy_name, &subdocument); \ } while (false) #define ADD_FLAG(_flags, _value) \ do { \ if (!BSON_ITER_HOLDS_BOOL (&iter)) { \ bson_set_error (&cursor->error, \ MONGOC_ERROR_COMMAND, \ MONGOC_ERROR_COMMAND_INVALID_ARG, \ "invalid option %s, should be type bool", \ key); \ return false; \ } \ if (bson_iter_as_bool (&iter)) { \ *_flags |= _value; \ } \ } while (false); static bool _mongoc_cursor_flags (mongoc_cursor_t *cursor, mongoc_server_stream_t *stream, mongoc_query_flags_t *flags /* OUT */) { bson_iter_t iter; const char *key; *flags = MONGOC_QUERY_NONE; if (!bson_iter_init (&iter, &cursor->opts)) { bson_set_error (&cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Invalid 'opts' parameter."); return false; } while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) { ADD_FLAG (flags, MONGOC_QUERY_PARTIAL); } else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) { ADD_FLAG (flags, MONGOC_QUERY_AWAIT_DATA); } else if (!strcmp (key, MONGOC_CURSOR_EXHAUST)) { ADD_FLAG (flags, MONGOC_QUERY_EXHAUST); } else if (!strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT)) { ADD_FLAG (flags, MONGOC_QUERY_NO_CURSOR_TIMEOUT); } else if (!strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY)) { ADD_FLAG (flags, MONGOC_QUERY_OPLOG_REPLAY); } else if (!strcmp (key, MONGOC_CURSOR_TAILABLE)) { ADD_FLAG (flags, MONGOC_QUERY_TAILABLE_CURSOR); } } if (cursor->slave_ok) { *flags |= MONGOC_QUERY_SLAVE_OK; } else if (cursor->server_id_set && (stream->topology_type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY || stream->topology_type == MONGOC_TOPOLOGY_RS_NO_PRIMARY) && stream->sd->type != MONGOC_SERVER_RS_PRIMARY) { *flags |= MONGOC_QUERY_SLAVE_OK; } return true; } static bson_t * _mongoc_cursor_parse_opts_for_op_query (mongoc_cursor_t *cursor, mongoc_server_stream_t *stream, bson_t *query /* OUT */, bson_t *fields /* OUT */, mongoc_query_flags_t *flags /* OUT */, int32_t *skip /* OUT */) { bool pushed_dollar_query; bson_iter_t iter; uint32_t len; const uint8_t *data; bson_t subdocument; const char *key; char *dollar_modifier; *flags = MONGOC_QUERY_NONE; *skip = 0; /* assume we'll send filter straight to server, like "{a: 1}". if we find an * opt we must add, like "sort", we push the query like "$query: {a: 1}", * then add a query modifier for the option, in this example "$orderby". */ pushed_dollar_query = false; if (!bson_iter_init (&iter, &cursor->opts)) { OPT_BSON_ERR ("Invalid 'opts' parameter."); } while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); /* most common options first */ if (!strcmp (key, MONGOC_CURSOR_PROJECTION)) { OPT_CHECK (DOCUMENT); bson_iter_document (&iter, &len, &data); if (!bson_init_static (&subdocument, data, (size_t) len)) { OPT_BSON_ERR ("Invalid 'projection' subdocument in 'opts'."); } bson_copy_to (&subdocument, fields); } else if (!strcmp (key, MONGOC_CURSOR_SORT)) { PUSH_DOLLAR_QUERY (); OPT_SUBDOCUMENT (sort, orderby); } else if (!strcmp (key, MONGOC_CURSOR_SKIP)) { OPT_CHECK_INT (); *skip = (int32_t) bson_iter_as_int64 (&iter); } /* the rest of the options, alphabetically */ else if (!strcmp (key, MONGOC_CURSOR_ALLOW_PARTIAL_RESULTS)) { OPT_FLAG (MONGOC_QUERY_PARTIAL); } else if (!strcmp (key, MONGOC_CURSOR_AWAIT_DATA)) { OPT_FLAG (MONGOC_QUERY_AWAIT_DATA); } else if (!strcmp (key, MONGOC_CURSOR_COMMENT)) { OPT_CHECK (UTF8); PUSH_DOLLAR_QUERY (); BSON_APPEND_UTF8 (query, "$comment", bson_iter_utf8 (&iter, NULL)); } else if (!strcmp (key, MONGOC_CURSOR_HINT)) { if (BSON_ITER_HOLDS_UTF8 (&iter)) { PUSH_DOLLAR_QUERY (); BSON_APPEND_UTF8 (query, "$hint", bson_iter_utf8 (&iter, NULL)); } else if (BSON_ITER_HOLDS_DOCUMENT (&iter)) { PUSH_DOLLAR_QUERY (); OPT_SUBDOCUMENT (hint, hint); } else { OPT_ERR ("Wrong type for 'hint' field in 'opts'."); } } else if (!strcmp (key, MONGOC_CURSOR_MAX)) { PUSH_DOLLAR_QUERY (); OPT_SUBDOCUMENT (max, max); } else if (!strcmp (key, MONGOC_CURSOR_MAX_SCAN)) { OPT_CHECK_INT (); PUSH_DOLLAR_QUERY (); BSON_APPEND_INT64 (query, "$maxScan", bson_iter_as_int64 (&iter)); } else if (!strcmp (key, MONGOC_CURSOR_MAX_TIME_MS)) { OPT_CHECK_INT (); PUSH_DOLLAR_QUERY (); BSON_APPEND_INT64 (query, "$maxTimeMS", bson_iter_as_int64 (&iter)); } else if (!strcmp (key, MONGOC_CURSOR_MIN)) { PUSH_DOLLAR_QUERY (); OPT_SUBDOCUMENT (min, min); } else if (!strcmp (key, MONGOC_CURSOR_READ_CONCERN)) { OPT_ERR ("Set readConcern on client, database, or collection," " not in a query."); } else if (!strcmp (key, MONGOC_CURSOR_RETURN_KEY)) { OPT_CHECK (BOOL); PUSH_DOLLAR_QUERY (); BSON_APPEND_BOOL (query, "$returnKey", bson_iter_as_bool (&iter)); } else if (!strcmp (key, MONGOC_CURSOR_SHOW_RECORD_ID)) { OPT_CHECK (BOOL); PUSH_DOLLAR_QUERY (); BSON_APPEND_BOOL (query, "$showDiskLoc", bson_iter_as_bool (&iter)); } else if (!strcmp (key, MONGOC_CURSOR_SNAPSHOT)) { OPT_CHECK (BOOL); PUSH_DOLLAR_QUERY (); BSON_APPEND_BOOL (query, "$snapshot", bson_iter_as_bool (&iter)); } else if (!strcmp (key, MONGOC_CURSOR_COLLATION)) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "Collation is not supported by this server"); return NULL; } /* singleBatch limit and batchSize are handled in _mongoc_n_return, * exhaust noCursorTimeout oplogReplay tailable in _mongoc_cursor_flags * maxAwaitTimeMS is handled in _mongoc_cursor_prepare_getmore_command */ else if (strcmp (key, MONGOC_CURSOR_SINGLE_BATCH) && strcmp (key, MONGOC_CURSOR_LIMIT) && strcmp (key, MONGOC_CURSOR_BATCH_SIZE) && strcmp (key, MONGOC_CURSOR_EXHAUST) && strcmp (key, MONGOC_CURSOR_NO_CURSOR_TIMEOUT) && strcmp (key, MONGOC_CURSOR_OPLOG_REPLAY) && strcmp (key, MONGOC_CURSOR_TAILABLE) && strcmp (key, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) { /* pass unrecognized options to server, prefixed with $ */ PUSH_DOLLAR_QUERY (); dollar_modifier = bson_strdup_printf ("$%s", key); bson_append_iter (query, dollar_modifier, -1, &iter); bson_free (dollar_modifier); } } if (!_mongoc_cursor_flags (cursor, stream, flags)) { /* cursor->error is set */ return NULL; } return pushed_dollar_query ? query : &cursor->filter; } #undef OPT_CHECK #undef OPT_ERR #undef OPT_BSON_ERR #undef OPT_FLAG #undef OPT_SUBDOCUMENT static const bson_t * _mongoc_cursor_op_query (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream) { int64_t started; uint32_t request_id; mongoc_rpc_t rpc; const char *cmd_name; /* for command monitoring */ const bson_t *query_ptr; bson_t query = BSON_INITIALIZER; bson_t fields = BSON_INITIALIZER; mongoc_query_flags_t flags; mongoc_apply_read_prefs_result_t result = READ_PREFS_RESULT_INIT; const bson_t *ret = NULL; bool succeeded = false; ENTRY; started = bson_get_monotonic_time (); cursor->sent = true; cursor->operation_id = ++cursor->client->cluster.operation_id; request_id = ++cursor->client->cluster.request_id; rpc.header.msg_len = 0; rpc.header.request_id = request_id; rpc.header.response_to = 0; rpc.header.opcode = MONGOC_OPCODE_QUERY; rpc.query.flags = MONGOC_QUERY_NONE; rpc.query.collection = cursor->ns; rpc.query.skip = 0; rpc.query.n_return = 0; rpc.query.fields = NULL; if (cursor->is_command) { /* "filter" isn't a query, it's like {commandName: ... }*/ cmd_name = _mongoc_get_command_name (&cursor->filter); BSON_ASSERT (cmd_name); } else { cmd_name = "find"; } query_ptr = _mongoc_cursor_parse_opts_for_op_query ( cursor, server_stream, &query, &fields, &flags, &rpc.query.skip); if (!query_ptr) { /* invalid opts. cursor->error is set */ GOTO (done); } apply_read_preferences ( cursor->read_prefs, server_stream, query_ptr, flags, &result); rpc.query.query = bson_get_data (result.query_with_read_prefs); rpc.query.flags = result.flags; rpc.query.n_return = _mongoc_n_return (cursor); if (!bson_empty (&fields)) { rpc.query.fields = bson_get_data (&fields); } if (!_mongoc_cursor_monitor_legacy_query (cursor, server_stream, cmd_name)) { GOTO (done); } if (!mongoc_cluster_sendv_to_server (&cursor->client->cluster, &rpc, server_stream, NULL, &cursor->error)) { GOTO (done); } _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 query. Expected %d, got %d.", request_id, cursor->rpc.header.response_to); GOTO (done); } if (!_mongoc_rpc_check_ok (&cursor->rpc, (bool) cursor->is_command, cursor->client->error_api_version, &cursor->error, &cursor->error_doc)) { 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); if (_mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_EXHAUST)) { cursor->in_exhaust = true; cursor->client->in_exhaust = true; } _mongoc_cursor_monitor_succeeded (cursor, bson_get_monotonic_time () - started, true, /* first_batch */ server_stream, cmd_name); cursor->done = false; cursor->end_of_event = false; succeeded = true; _mongoc_read_from_buffer (cursor, &ret); done: if (!succeeded) { _mongoc_cursor_monitor_failed ( cursor, bson_get_monotonic_time () - started, server_stream, cmd_name); } apply_read_prefs_result_cleanup (&result); bson_destroy (&query); bson_destroy (&fields); if (!ret) { cursor->done = true; } RETURN (ret); } bool _mongoc_cursor_run_command (mongoc_cursor_t *cursor, const bson_t *command, bson_t *reply) { mongoc_cluster_t *cluster; mongoc_server_stream_t *server_stream; mongoc_cmd_parts_t parts; char db[MONGOC_NAMESPACE_MAX]; bool ret = false; ENTRY; cluster = &cursor->client->cluster; mongoc_cmd_parts_init (&parts, db, MONGOC_QUERY_NONE, command); parts.read_prefs = cursor->read_prefs; parts.assembled.operation_id = cursor->operation_id; server_stream = _mongoc_cursor_fetch_stream (cursor); if (!server_stream) { GOTO (done); } bson_strncpy (db, cursor->ns, cursor->dblen + 1); parts.assembled.db_name = db; if (!_mongoc_cursor_flags (cursor, server_stream, &parts.user_query_flags)) { GOTO (done); } if (cursor->write_concern && !mongoc_write_concern_is_default (cursor->write_concern) && server_stream->sd->max_wire_version >= WIRE_VERSION_CMD_WRITE_CONCERN) { mongoc_write_concern_append (cursor->write_concern, &parts.extra); } ret = mongoc_cluster_run_command_monitored ( cluster, &parts, server_stream, reply, &cursor->error); /* Read and Write Concern Spec: "Drivers SHOULD parse server replies for a * "writeConcernError" field and report the error only in command-specific * helper methods that take a separate write concern parameter or an options * parameter that may contain a write concern option. * * Only command helpers with names like "_with_write_concern" can create * cursors with a non-NULL write_concern field. */ if (ret && cursor->write_concern) { ret = !_mongoc_parse_wc_err (reply, &cursor->error); } done: mongoc_server_stream_cleanup (server_stream); mongoc_cmd_parts_cleanup (&parts); return ret; } 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 (MONGOC_CURSOR_ORDERBY, query_field)) { *cmd_field = MONGOC_CURSOR_SORT; *len = MONGOC_CURSOR_SORT_LEN; } else if (!strcmp (MONGOC_CURSOR_SHOW_DISK_LOC, query_field)) { /* <= MongoDb 3.0 */ *cmd_field = MONGOC_CURSOR_SHOW_RECORD_ID; *len = MONGOC_CURSOR_SHOW_RECORD_ID_LEN; } else if (!strcmp (MONGOC_CURSOR_HINT, query_field)) { *cmd_field = MONGOC_CURSOR_HINT; *len = MONGOC_CURSOR_HINT_LEN; } else if (!strcmp (MONGOC_CURSOR_COMMENT, query_field)) { *cmd_field = MONGOC_CURSOR_COMMENT; *len = MONGOC_CURSOR_COMMENT_LEN; } else if (!strcmp (MONGOC_CURSOR_MAX_SCAN, query_field)) { *cmd_field = MONGOC_CURSOR_MAX_SCAN; *len = MONGOC_CURSOR_MAX_SCAN_LEN; } else if (!strcmp (MONGOC_CURSOR_MAX_TIME_MS, query_field)) { *cmd_field = MONGOC_CURSOR_MAX_TIME_MS; *len = MONGOC_CURSOR_MAX_TIME_MS_LEN; } else if (!strcmp (MONGOC_CURSOR_MAX, query_field)) { *cmd_field = MONGOC_CURSOR_MAX; *len = MONGOC_CURSOR_MAX_LEN; } else if (!strcmp (MONGOC_CURSOR_MIN, query_field)) { *cmd_field = MONGOC_CURSOR_MIN; *len = MONGOC_CURSOR_MIN_LEN; } else if (!strcmp (MONGOC_CURSOR_RETURN_KEY, query_field)) { *cmd_field = MONGOC_CURSOR_RETURN_KEY; *len = MONGOC_CURSOR_RETURN_KEY_LEN; } else if (!strcmp (MONGOC_CURSOR_SNAPSHOT, query_field)) { *cmd_field = MONGOC_CURSOR_SNAPSHOT; *len = MONGOC_CURSOR_SNAPSHOT_LEN; } else { /* not a special command field, must be a query operator like $or */ return false; } return 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, mongoc_server_stream_t *server_stream) { const char *collection; int collection_len; bson_iter_t iter; _mongoc_cursor_collection (cursor, &collection, &collection_len); bson_append_utf8 (command, MONGOC_CURSOR_FIND, MONGOC_CURSOR_FIND_LEN, collection, collection_len); bson_append_document ( command, MONGOC_CURSOR_FILTER, MONGOC_CURSOR_FILTER_LEN, &cursor->filter); bson_iter_init (&iter, &cursor->opts); while (bson_iter_next (&iter)) { /* don't append "maxAwaitTimeMS" */ if (!strcmp (bson_iter_key (&iter), MONGOC_CURSOR_COLLATION) && server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "Collation is not supported by this server"); MARK_FAILED (cursor); return false; } else if (strcmp (bson_iter_key (&iter), MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) { if (!bson_append_iter (command, bson_iter_key (&iter), -1, &iter)) { bson_set_error (&cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Cursor opts too large"); MARK_FAILED (cursor); return false; } } } 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, MONGOC_CURSOR_READ_CONCERN, MONGOC_CURSOR_READ_CONCERN_LEN, read_concern_bson); } return true; } static const bson_t * _mongoc_cursor_find_command (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream) { bson_t command = BSON_INITIALIZER; const bson_t *bson = NULL; ENTRY; if (!_mongoc_cursor_prepare_find_command (cursor, &command, server_stream)) { 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); } static bool _mongoc_cursor_monitor_legacy_get_more (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream) { bson_t doc; char db[MONGOC_NAMESPACE_MAX]; mongoc_client_t *client; mongoc_apm_command_started_t event; ENTRY; client = cursor->client; if (!client->apm_callbacks.started) { /* successful */ RETURN (true); } bson_init (&doc); if (!_mongoc_cursor_prepare_getmore_command (cursor, &doc)) { bson_destroy (&doc); RETURN (false); } bson_strncpy (db, cursor->ns, cursor->dblen + 1); mongoc_apm_command_started_init (&event, &doc, db, "getMore", client->cluster.request_id, cursor->operation_id, &server_stream->sd->host, server_stream->sd->id, client->apm_context); client->apm_callbacks.started (&event); mongoc_apm_command_started_cleanup (&event); bson_destroy (&doc); RETURN (true); } bool _mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream) { int64_t started; mongoc_rpc_t rpc; uint32_t request_id; mongoc_cluster_t *cluster; mongoc_query_flags_t flags; ENTRY; started = bson_get_monotonic_time (); cluster = &cursor->client->cluster; if (!_mongoc_cursor_flags (cursor, server_stream, &flags)) { GOTO (fail); } if (cursor->in_exhaust) { request_id = (uint32_t) cursor->rpc.header.request_id; } else { request_id = ++cluster->request_id; rpc.get_more.cursor_id = cursor->rpc.reply.cursor_id; rpc.header.msg_len = 0; rpc.header.request_id = request_id; rpc.header.response_to = 0; rpc.header.opcode = MONGOC_OPCODE_GET_MORE; rpc.get_more.zero = 0; rpc.get_more.collection = cursor->ns; if (flags & MONGOC_QUERY_TAILABLE_CURSOR) { rpc.get_more.n_return = 0; } else { rpc.get_more.n_return = _mongoc_n_return (cursor); } if (!_mongoc_cursor_monitor_legacy_get_more (cursor, server_stream)) { GOTO (fail); } if (!mongoc_cluster_sendv_to_server ( cluster, &rpc, server_stream, NULL, &cursor->error)) { GOTO (fail); } } _mongoc_buffer_clear (&cursor->buffer, false); if (!_mongoc_client_recv (cursor->client, &cursor->rpc, &cursor->buffer, server_stream, &cursor->error)) { GOTO (fail); } 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 (fail); } 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 (fail); } if (!_mongoc_rpc_check_ok (&cursor->rpc, false /* is_command */, cursor->client->error_api_version, &cursor->error, &cursor->error_doc)) { GOTO (fail); } 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); _mongoc_cursor_monitor_succeeded (cursor, bson_get_monotonic_time () - started, false, /* not first batch */ server_stream, "getMore"); RETURN (true); fail: _mongoc_cursor_monitor_failed ( cursor, bson_get_monotonic_time () - started, server_stream, "getMore"); RETURN (false); } bool mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error) { ENTRY; RETURN (mongoc_cursor_error_document (cursor, error, NULL)); } bool mongoc_cursor_error_document (mongoc_cursor_t *cursor, bson_error_t *error, const bson_t **doc) { bool ret; ENTRY; BSON_ASSERT (cursor); if (cursor->iface.error_document) { ret = cursor->iface.error_document (cursor, error, doc); } else { ret = _mongoc_cursor_error_document (cursor, error, doc); } RETURN (ret); } bool _mongoc_cursor_error_document (mongoc_cursor_t *cursor, bson_error_t *error, const bson_t **doc) { ENTRY; BSON_ASSERT (cursor); if (BSON_UNLIKELY (CURSOR_FAILED (cursor))) { bson_set_error (error, cursor->error.domain, cursor->error.code, "%s", cursor->error.message); if (doc) { *doc = &cursor->error_doc; } RETURN (true); } if (doc) { *doc = NULL; } 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; } if (cursor->done) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot advance a completed or 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) { int64_t limit; const bson_t *b = NULL; bool tailable; ENTRY; BSON_ASSERT (cursor); if (bson) { *bson = NULL; } /* * If we reached our limit, make sure we mark this as done and do not try to * make further progress. We also set end_of_event so that * mongoc_cursor_more will be false. */ limit = mongoc_cursor_get_limit (cursor); if (limit && cursor->count >= llabs (limit)) { cursor->done = true; cursor->end_of_event = 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: tailable = _mongoc_cursor_get_opt_bool (cursor, "tailable"); cursor->done = (cursor->end_of_event && ((cursor->in_exhaust && !cursor->rpc.reply.cursor_id) || (!b && !tailable))); 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->done && 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->server_id) { MONGOC_WARNING ("%s(): Must send query before fetching peer.", BSON_FUNC); return; } description = mongoc_topology_server_by_id ( cursor->client->topology, cursor->server_id, &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->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->filter, &_clone->filter); bson_copy_to (&cursor->opts, &_clone->opts); bson_copy_to (&cursor->error_doc, &_clone->error_doc); 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->done; } 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); _mongoc_cursor_set_opt_int64 ( cursor, MONGOC_CURSOR_BATCH_SIZE, (int64_t) batch_size); } uint32_t mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor) { BSON_ASSERT (cursor); return (uint32_t) _mongoc_cursor_get_opt_int64 ( cursor, MONGOC_CURSOR_BATCH_SIZE, 0); } bool mongoc_cursor_set_limit (mongoc_cursor_t *cursor, int64_t limit) { BSON_ASSERT (cursor); if (!cursor->sent) { if (limit < 0) { return _mongoc_cursor_set_opt_int64 ( cursor, MONGOC_CURSOR_LIMIT, -limit) && _mongoc_cursor_set_opt_bool ( cursor, MONGOC_CURSOR_SINGLE_BATCH, true); } else { return _mongoc_cursor_set_opt_int64 ( cursor, MONGOC_CURSOR_LIMIT, limit); } } else { return false; } } int64_t mongoc_cursor_get_limit (const mongoc_cursor_t *cursor) { int64_t limit; bool single_batch; BSON_ASSERT (cursor); limit = _mongoc_cursor_get_opt_int64 (cursor, MONGOC_CURSOR_LIMIT, 0); single_batch = _mongoc_cursor_get_opt_bool (cursor, MONGOC_CURSOR_SINGLE_BATCH); if (limit > 0 && single_batch) { limit = -limit; } return limit; } bool mongoc_cursor_set_hint (mongoc_cursor_t *cursor, uint32_t server_id) { BSON_ASSERT (cursor); if (cursor->server_id) { MONGOC_ERROR ("mongoc_cursor_set_hint: server_id already set"); return false; } if (!server_id) { MONGOC_ERROR ("mongoc_cursor_set_hint: cannot set server_id to 0"); return false; } cursor->server_id = server_id; cursor->server_id_set = true; return true; } uint32_t mongoc_cursor_get_hint (const mongoc_cursor_t *cursor) { BSON_ASSERT (cursor); return cursor->server_id; } 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) { _mongoc_cursor_set_opt_int64 ( cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, (int64_t) max_await_time_ms); } } uint32_t mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor) { bson_iter_t iter; BSON_ASSERT (cursor); if (bson_iter_init_find ( &iter, &cursor->opts, MONGOC_CURSOR_MAX_AWAIT_TIME_MS)) { return (uint32_t) bson_iter_as_int64 (&iter); } return 0; } /* *-------------------------------------------------------------------------- * * mongoc_cursor_new_from_command_reply -- * * Low-level function to initialize a mongoc_cursor_t from the * reply to a command like "aggregate", "find", or "listCollections". * * Useful in drivers that wrap the C driver; in applications, use * high-level functions like mongoc_collection_aggregate instead. * * Returns: * A cursor. * * Side effects: * On failure, the cursor's error is set: retrieve it with * mongoc_cursor_error. On success or failure, "reply" is * destroyed. * *-------------------------------------------------------------------------- */ mongoc_cursor_t * mongoc_cursor_new_from_command_reply (mongoc_client_t *client, bson_t *reply, uint32_t server_id) { mongoc_cursor_t *cursor; bson_t cmd = BSON_INITIALIZER; BSON_ASSERT (client); BSON_ASSERT (reply); cursor = _mongoc_cursor_new_with_opts ( client, NULL, false /* is_command */, NULL, NULL, NULL, NULL); _mongoc_cursor_cursorid_init (cursor, &cmd); _mongoc_cursor_cursorid_init_with_reply (cursor, reply, server_id); bson_destroy (&cmd); return cursor; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cursor.h0000664000175000017500000000604613210321137022562 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-macros.h" #include "mongoc-host-list.h" BSON_BEGIN_DECLS typedef struct _mongoc_cursor_t mongoc_cursor_t; /* forward decl */ struct _mongoc_client_t; MONGOC_EXPORT (mongoc_cursor_t *) mongoc_cursor_clone (const mongoc_cursor_t *cursor) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (void) mongoc_cursor_destroy (mongoc_cursor_t *cursor); MONGOC_EXPORT (bool) mongoc_cursor_more (mongoc_cursor_t *cursor); MONGOC_EXPORT (bool) mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson); MONGOC_EXPORT (bool) mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_cursor_error_document (mongoc_cursor_t *cursor, bson_error_t *error, const bson_t **doc); MONGOC_EXPORT (void) mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host); MONGOC_EXPORT (bool) mongoc_cursor_is_alive (const mongoc_cursor_t *cursor); MONGOC_EXPORT (const bson_t *) mongoc_cursor_current (const mongoc_cursor_t *cursor); MONGOC_EXPORT (void) mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size); MONGOC_EXPORT (uint32_t) mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor); MONGOC_EXPORT (bool) mongoc_cursor_set_limit (mongoc_cursor_t *cursor, int64_t limit); MONGOC_EXPORT (int64_t) mongoc_cursor_get_limit (const mongoc_cursor_t *cursor); /* These names include the term "hint" for backward compatibility, should be * mongoc_cursor_get_server_id, mongoc_cursor_set_server_id. */ MONGOC_EXPORT (bool) mongoc_cursor_set_hint (mongoc_cursor_t *cursor, uint32_t server_id); MONGOC_EXPORT (uint32_t) mongoc_cursor_get_hint (const mongoc_cursor_t *cursor); MONGOC_EXPORT (int64_t) mongoc_cursor_get_id (const mongoc_cursor_t *cursor); MONGOC_EXPORT (void) mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor, uint32_t max_await_time_ms); MONGOC_EXPORT (uint32_t) mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor); MONGOC_EXPORT (mongoc_cursor_t *) mongoc_cursor_new_from_command_reply (struct _mongoc_client_t *client, bson_t *reply, uint32_t server_id) BSON_GNUC_WARN_UNUSED_RESULT; BSON_END_DECLS #endif /* MONGOC_CURSOR_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cyrus-private.h0000664000175000017500000000377313210321137024066 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_CYRUS_PRIVATE_H #define MONGOC_CYRUS_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-uri.h" #include "mongoc-cluster-private.h" #include "mongoc-sasl-private.h" #include #include #include BSON_BEGIN_DECLS typedef struct _mongoc_cyrus_t mongoc_cyrus_t; struct _mongoc_cyrus_t { mongoc_sasl_t credentials; sasl_callback_t callbacks[5]; sasl_conn_t *conn; bool done; int step; sasl_interact_t *interact; }; #ifndef SASL_CALLBACK_FN #define SASL_CALLBACK_FN(_f) ((int (*) (void)) (_f)) #endif void _mongoc_cyrus_init (mongoc_cyrus_t *sasl); bool _mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl, mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error); int _mongoc_cyrus_log (mongoc_cyrus_t *sasl, int level, const char *message); void _mongoc_cyrus_destroy (mongoc_cyrus_t *sasl); bool _mongoc_cyrus_step (mongoc_cyrus_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_CYRUS_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-cyrus.c0000664000175000017500000002775513210321137022417 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_CYRUS #include #include "mongoc-error.h" #include "mongoc-cyrus-private.h" #include "mongoc-util-private.h" #include "mongoc-trace-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "CYRUS-SASL" int _mongoc_cyrus_log (mongoc_cyrus_t *sasl, int level, const char *message) { TRACE ("SASL Log; level=%d: message=%s", level, message); return SASL_OK; } bool _mongoc_cyrus_set_mechanism (mongoc_cyrus_t *sasl, const char *mechanism, bson_error_t *error) { bson_string_t *str = bson_string_new (""); const char **mechs = sasl_global_listmech (); int i = 0; bool ok = false; BSON_ASSERT (sasl); for (i = 0; mechs[i]; i++) { if (!strcmp (mechs[i], mechanism)) { ok = true; break; } bson_string_append (str, mechs[i]); if (mechs[i + 1]) { bson_string_append (str, ","); } } if (ok) { bson_free (sasl->credentials.mechanism); sasl->credentials.mechanism = mechanism ? bson_strdup (mechanism) : NULL; } else { bson_set_error (error, MONGOC_ERROR_SASL, SASL_NOMECH, "SASL Failure: Unsupported mechanism by client: %s. " "Available mechanisms: %s", mechanism, str->str); } bson_string_free (str, 0); return ok; } static int _mongoc_cyrus_get_pass (mongoc_cyrus_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->credentials.pass; } if (result_len) { *result_len = sasl->credentials.pass ? (unsigned) strlen (sasl->credentials.pass) : 0; } return (sasl->credentials.pass != NULL) ? SASL_OK : SASL_FAIL; } static int _mongoc_cyrus_canon_user (sasl_conn_t *conn, mongoc_cyrus_t *sasl, const char *in, unsigned inlen, unsigned flags, const char *user_realm, char *out, unsigned out_max, unsigned *out_len) { TRACE ("Canonicalizing %s (%" PRIu32 ")\n", in, inlen); strcpy (out, in); *out_len = inlen; return SASL_OK; } static int _mongoc_cyrus_get_user (mongoc_cyrus_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->credentials.user; } if (result_len) { *result_len = sasl->credentials.user ? (unsigned) strlen (sasl->credentials.user) : 0; } return (sasl->credentials.user != NULL) ? SASL_OK : SASL_FAIL; } void _mongoc_cyrus_init (mongoc_cyrus_t *sasl) { sasl_callback_t callbacks[] = { {SASL_CB_AUTHNAME, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, {SASL_CB_USER, SASL_CALLBACK_FN (_mongoc_cyrus_get_user), sasl}, {SASL_CB_PASS, SASL_CALLBACK_FN (_mongoc_cyrus_get_pass), sasl}, {SASL_CB_CANON_USER, SASL_CALLBACK_FN (_mongoc_cyrus_canon_user), 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->interact = NULL; sasl->credentials.mechanism = NULL; sasl->credentials.user = NULL; sasl->credentials.pass = NULL; sasl->credentials.service_name = NULL; sasl->credentials.service_host = NULL; } bool _mongoc_cyrus_new_from_cluster (mongoc_cyrus_t *sasl, mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error) { const char *mechanism; char real_name[BSON_HOST_NAME_MAX + 1]; _mongoc_cyrus_init (sasl); mechanism = mongoc_uri_get_auth_mechanism (cluster->uri); if (!mechanism) { mechanism = "GSSAPI"; } if (!_mongoc_cyrus_set_mechanism (sasl, mechanism, error)) { _mongoc_cyrus_destroy (sasl); return false; } _mongoc_sasl_set_pass ((mongoc_sasl_t *) sasl, mongoc_uri_get_password (cluster->uri)); _mongoc_sasl_set_user ((mongoc_sasl_t *) sasl, mongoc_uri_get_username (cluster->uri)); _mongoc_sasl_set_properties ((mongoc_sasl_t *) sasl, 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 (sasl->credentials.canonicalize_host_name && _mongoc_sasl_get_canonicalized_name ( stream, real_name, sizeof real_name, error)) { _mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, real_name); } else { _mongoc_sasl_set_service_host ((mongoc_sasl_t *) sasl, hostname); } return true; } void _mongoc_cyrus_destroy (mongoc_cyrus_t *sasl) { BSON_ASSERT (sasl); if (sasl->conn) { sasl_dispose (&sasl->conn); } bson_free (sasl->credentials.user); bson_free (sasl->credentials.pass); bson_free (sasl->credentials.mechanism); bson_free (sasl->credentials.service_name); bson_free (sasl->credentials.service_host); } static bool _mongoc_cyrus_is_failure (int status, bson_error_t *error) { bool ret = (status < 0); TRACE ("Got status: %d ok is %d, continue=%d interact=%d\n", status, SASL_OK, SASL_CONTINUE, SASL_INTERACT); if (ret) { switch (status) { case SASL_NOMEM: bson_set_error (error, MONGOC_ERROR_SASL, status, "SASL Failure: insufficient memory."); break; case SASL_NOMECH: { bson_string_t *str = bson_string_new ("available mechanisms: "); const char **mechs = sasl_global_listmech (); int i = 0; for (i = 0; mechs[i]; i++) { bson_string_append (str, mechs[i]); if (mechs[i + 1]) { bson_string_append (str, ","); } } bson_set_error (error, MONGOC_ERROR_SASL, status, "SASL Failure: failure to negotiate mechanism (%s)", str->str); bson_string_free (str, 0); } 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_cyrus_start (mongoc_cyrus_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->credentials.service_name) { service_name = sasl->credentials.service_name; } if (sasl->credentials.service_host) { service_host = sasl->credentials.service_host; } status = sasl_client_new ( service_name, service_host, NULL, NULL, sasl->callbacks, 0, &sasl->conn); TRACE ("Created new sasl client %s", status == SASL_OK ? "successfully" : "UNSUCCESSFULLY"); if (_mongoc_cyrus_is_failure (status, error)) { return false; } status = sasl_client_start (sasl->conn, sasl->credentials.mechanism, &sasl->interact, &raw, &raw_len, &mechanism); TRACE ("Started the sasl client %s", status == SASL_CONTINUE ? "successfully" : "UNSUCCESSFULLY"); if (_mongoc_cyrus_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_cyrus_is_failure (status, error)) { return false; } return true; } bool _mongoc_cyrus_step (mongoc_cyrus_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); TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen); sasl->step++; if (sasl->step == 1) { return _mongoc_cyrus_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; } TRACE ("Running %d, inbuflen: %" PRIu32, sasl->step, inbuflen); if (!inbuflen) { bson_set_error (error, MONGOC_ERROR_SASL, MONGOC_ERROR_CLIENT_AUTHENTICATE, "SASL Failure: no payload provided from server: %s", sasl_errdetail (sasl->conn)); return false; } status = sasl_decode64 ( (char *) inbuf, inbuflen, (char *) outbuf, outbufmax, outbuflen); if (_mongoc_cyrus_is_failure (status, error)) { return false; } TRACE ("%s", "Running client_step"); status = sasl_client_step ( sasl->conn, (char *) outbuf, *outbuflen, &sasl->interact, &raw, &rawlen); TRACE ("%s sent a client step", status == SASL_OK ? "Successfully" : "UNSUCCESSFULLY"); if (_mongoc_cyrus_is_failure (status, error)) { return false; } status = sasl_encode64 (raw, rawlen, (char *) outbuf, outbufmax, outbuflen); if (_mongoc_cyrus_is_failure (status, error)) { return false; } return true; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-database-private.h0000664000175000017500000000324013210321137024452 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_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.3.4/src/libmongoc/src/mongoc/mongoc-database.c0000664000175000017500000010530113210321137022776 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-private.h" #include "mongoc-util-private.h" #include "mongoc-write-concern-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); /* Server Selection Spec: "The generic command method has a default read * preference of mode 'primary'. The generic command method MUST ignore any * default read preference from client, database or collection * configuration. The generic command method SHOULD allow an optional read * preference argument." */ 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); /* Server Selection Spec: "The generic command method has a default read * preference of mode 'primary'. The generic command method MUST ignore any * default read preference from client, database or collection * configuration. The generic command method SHOULD allow an optional read * preference argument." */ return mongoc_client_command_simple ( database->client, database->name, command, read_prefs, reply, error); } bool mongoc_database_read_command_with_opts (mongoc_database_t *database, const bson_t *command, const mongoc_read_prefs_t *read_prefs, const bson_t *opts, bson_t *reply, bson_error_t *error) { return _mongoc_client_command_with_opts ( database->client, database->name, command, MONGOC_CMD_READ, opts, MONGOC_QUERY_NONE, COALESCE (read_prefs, database->read_prefs), database->read_concern, database->write_concern, reply, error); } bool mongoc_database_write_command_with_opts (mongoc_database_t *database, const bson_t *command, const bson_t *opts, bson_t *reply, bson_error_t *error) { return _mongoc_client_command_with_opts (database->client, database->name, command, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, database->read_prefs, database->read_concern, database->write_concern, reply, error); } bool mongoc_database_read_write_command_with_opts ( mongoc_database_t *database, const bson_t *command, const mongoc_read_prefs_t *read_prefs /* IGNORED */, const bson_t *opts, bson_t *reply, bson_error_t *error) { return _mongoc_client_command_with_opts ( database->client, database->name, command, MONGOC_CMD_RW, opts, MONGOC_QUERY_NONE, COALESCE (read_prefs, database->read_prefs), database->read_concern, database->write_concern, 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) { return mongoc_database_drop_with_opts (database, NULL, error); } bool mongoc_database_drop_with_opts (mongoc_database_t *database, const bson_t *opts, bson_error_t *error) { bool ret; bson_t cmd; BSON_ASSERT (database); bson_init (&cmd); bson_append_int32 (&cmd, "dropDatabase", 12, 1); ret = _mongoc_client_command_with_opts (database->client, database->name, &cmd, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, database->read_prefs, database->read_concern, database->write_concern, NULL, /* reply */ 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 opts; 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); bson_init (&opts); bson_append_int64 (&opts, "limit", 5, 1); bson_append_bool (&opts, "singleBatch", 11, true); cursor = mongoc_collection_find_with_opts (collection, &query, &opts, 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_insert ( collection, MONGOC_INSERT_NONE, &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_destroy (&opts); 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; } /* Enumerate Collections Spec: "run listCollections on the primary node in * replicaset mode" */ read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor = mongoc_collection_find_with_opts ( col, 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; 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); } /* Enumerate Collections Spec: "run listCollections on the primary node in * replicaset mode" */ cursor = _mongoc_cursor_new_with_opts (database->client, database->name, true /* is_command */, 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); 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 *opts, 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 (opts) { if (bson_iter_init_find (&iter, opts, "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, opts, "size")) { if (!BSON_ITER_HOLDS_INT (&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, opts, "max")) { if (!BSON_ITER_HOLDS_INT (&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, opts, "storageEngine")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_set_error ( error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"storageEngine\" 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 (_mongoc_client_command_with_opts (database->client, database->name, &cmd, MONGOC_CMD_WRITE, opts, MONGOC_QUERY_NONE, database->read_prefs, database->read_concern, database->write_concern, NULL, /* reply */ 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.3.4/src/libmongoc/src/mongoc/mongoc-database.h0000664000175000017500000001317213210321137023007 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-macros.h" #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; MONGOC_EXPORT (const char *) mongoc_database_get_name (mongoc_database_t *database); MONGOC_EXPORT (bool) mongoc_database_remove_user (mongoc_database_t *database, const char *username, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_database_remove_all_users (mongoc_database_t *database, bson_error_t *error); MONGOC_EXPORT (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); MONGOC_EXPORT (void) mongoc_database_destroy (mongoc_database_t *database); MONGOC_EXPORT (mongoc_database_t *) mongoc_database_copy (mongoc_database_t *database); MONGOC_EXPORT (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); MONGOC_EXPORT (bool) mongoc_database_read_command_with_opts (mongoc_database_t *database, const bson_t *command, const mongoc_read_prefs_t *read_prefs, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_database_write_command_with_opts (mongoc_database_t *database, const bson_t *command, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_database_read_write_command_with_opts ( mongoc_database_t *database, const bson_t *command, const mongoc_read_prefs_t *read_prefs /* IGNORED */, const bson_t *opts, bson_t *reply, bson_error_t *error); MONGOC_EXPORT (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); MONGOC_EXPORT (bool) mongoc_database_drop (mongoc_database_t *database, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_database_drop_with_opts (mongoc_database_t *database, const bson_t *opts, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_database_has_collection (mongoc_database_t *database, const char *name, bson_error_t *error); MONGOC_EXPORT (mongoc_collection_t *) mongoc_database_create_collection (mongoc_database_t *database, const char *name, const bson_t *options, bson_error_t *error); MONGOC_EXPORT (const mongoc_read_prefs_t *) mongoc_database_get_read_prefs (const mongoc_database_t *database); MONGOC_EXPORT (void) mongoc_database_set_read_prefs (mongoc_database_t *database, const mongoc_read_prefs_t *read_prefs); MONGOC_EXPORT (const mongoc_write_concern_t *) mongoc_database_get_write_concern (const mongoc_database_t *database); MONGOC_EXPORT (void) mongoc_database_set_write_concern (mongoc_database_t *database, const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (const mongoc_read_concern_t *) mongoc_database_get_read_concern (const mongoc_database_t *database); MONGOC_EXPORT (void) mongoc_database_set_read_concern (mongoc_database_t *database, const mongoc_read_concern_t *read_concern); MONGOC_EXPORT (mongoc_cursor_t *) mongoc_database_find_collections (mongoc_database_t *database, const bson_t *filter, bson_error_t *error); MONGOC_EXPORT (char **) mongoc_database_get_collection_names (mongoc_database_t *database, bson_error_t *error); MONGOC_EXPORT (mongoc_collection_t *) mongoc_database_get_collection (mongoc_database_t *database, const char *name); BSON_END_DECLS #endif /* MONGOC_DATABASE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-errno-private.h0000664000175000017500000000325713210321137024043 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_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)) #define MONGOC_ERRNO_IS_TIMEDOUT(errno) (errno == WSAETIMEDOUT) #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)) #define MONGOC_ERRNO_IS_TIMEDOUT(errno) (errno == ETIMEDOUT) #else #define MONGOC_ERRNO_IS_AGAIN(errno) \ ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK) || \ (errno == EINPROGRESS)) #define MONGOC_ERRNO_IS_TIMEDOUT(errno) (errno == ETIMEDOUT) #endif BSON_END_DECLS #endif /* MONGOC_ERRNO_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-error.h0000664000175000017500000000573613210321137022403 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 #define MONGOC_ERROR_API_VERSION_LEGACY 1 #define MONGOC_ERROR_API_VERSION_2 2 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_SERVER, /* Error API Version 2 only */ } 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, MONGOC_ERROR_GRIDFS_PROTOCOL_ERROR, /* Dup with query failure. */ MONGOC_ERROR_PROTOCOL_ERROR = 17, MONGOC_ERROR_WRITE_CONCERN_ERROR = 64, MONGOC_ERROR_DUPLICATE_KEY = 11000, } mongoc_error_code_t; BSON_END_DECLS #endif /* MONGOC_ERRORS_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h0000664000175000017500000000225413210321137025657 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; uint32_t max_time_ms; bson_t extra; }; BSON_END_DECLS #endif /* MONGOC_FIND_AND_MODIFY_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-find-and-modify.c0000664000175000017500000001224713210321137024205 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); bson_init (&opts->extra); 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; } void mongoc_find_and_modify_opts_get_sort (const mongoc_find_and_modify_opts_t *opts, bson_t *sort) { BSON_ASSERT (opts); BSON_ASSERT (sort); if (opts->sort) { bson_copy_to (opts->sort, sort); } else { bson_init (sort); } } 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; } void mongoc_find_and_modify_opts_get_update ( const mongoc_find_and_modify_opts_t *opts, bson_t *update) { BSON_ASSERT (opts); BSON_ASSERT (update); if (opts->update) { bson_copy_to (opts->update, update); } else { bson_init (update); } } 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; } void mongoc_find_and_modify_opts_get_fields ( const mongoc_find_and_modify_opts_t *opts, bson_t *fields) { BSON_ASSERT (opts); BSON_ASSERT (fields); if (opts->fields) { bson_copy_to (opts->fields, fields); } else { bson_init (fields); } } 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; } mongoc_find_and_modify_flags_t mongoc_find_and_modify_opts_get_flags ( const mongoc_find_and_modify_opts_t *opts) { BSON_ASSERT (opts); return opts->flags; } 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; } bool mongoc_find_and_modify_opts_get_bypass_document_validation ( const mongoc_find_and_modify_opts_t *opts) { BSON_ASSERT (opts); return opts->bypass_document_validation == MONGOC_BYPASS_DOCUMENT_VALIDATION_TRUE; } bool mongoc_find_and_modify_opts_set_max_time_ms ( mongoc_find_and_modify_opts_t *opts, uint32_t max_time_ms) { BSON_ASSERT (opts); opts->max_time_ms = max_time_ms; return true; } uint32_t mongoc_find_and_modify_opts_get_max_time_ms ( const mongoc_find_and_modify_opts_t *opts) { BSON_ASSERT (opts); return opts->max_time_ms; } bool mongoc_find_and_modify_opts_append (mongoc_find_and_modify_opts_t *opts, const bson_t *extra) { BSON_ASSERT (opts); BSON_ASSERT (extra); return bson_concat (&opts->extra, extra); } void mongoc_find_and_modify_opts_get_extra ( const mongoc_find_and_modify_opts_t *opts, bson_t *extra) { BSON_ASSERT (opts); BSON_ASSERT (extra); bson_copy_to (&opts->extra, extra); } /** * 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_destroy (&opts->extra); bson_free (opts); } } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-find-and-modify.h0000664000175000017500000000643013210321137024207 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 #include "mongoc-macros.h" 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_EXPORT (mongoc_find_and_modify_opts_t *) mongoc_find_and_modify_opts_new (void); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_set_sort (mongoc_find_and_modify_opts_t *opts, const bson_t *sort); MONGOC_EXPORT (void) mongoc_find_and_modify_opts_get_sort (const mongoc_find_and_modify_opts_t *opts, bson_t *sort); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_set_update (mongoc_find_and_modify_opts_t *opts, const bson_t *update); MONGOC_EXPORT (void) mongoc_find_and_modify_opts_get_update ( const mongoc_find_and_modify_opts_t *opts, bson_t *update); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_set_fields (mongoc_find_and_modify_opts_t *opts, const bson_t *fields); MONGOC_EXPORT (void) mongoc_find_and_modify_opts_get_fields ( const mongoc_find_and_modify_opts_t *opts, bson_t *fields); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_set_flags ( mongoc_find_and_modify_opts_t *opts, const mongoc_find_and_modify_flags_t flags); MONGOC_EXPORT (mongoc_find_and_modify_flags_t) mongoc_find_and_modify_opts_get_flags ( const mongoc_find_and_modify_opts_t *opts); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_set_bypass_document_validation ( mongoc_find_and_modify_opts_t *opts, bool bypass); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_get_bypass_document_validation ( const mongoc_find_and_modify_opts_t *opts); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_set_max_time_ms ( mongoc_find_and_modify_opts_t *opts, uint32_t max_time_ms); MONGOC_EXPORT (uint32_t) mongoc_find_and_modify_opts_get_max_time_ms ( const mongoc_find_and_modify_opts_t *opts); MONGOC_EXPORT (bool) mongoc_find_and_modify_opts_append (mongoc_find_and_modify_opts_t *opts, const bson_t *extra); MONGOC_EXPORT (void) mongoc_find_and_modify_opts_get_extra ( const mongoc_find_and_modify_opts_t *opts, bson_t *extra); MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-flags.h0000664000175000017500000001106213210321137022333 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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h0000664000175000017500000000271113210321137026054 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_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); mongoc_gridfs_file_list_t * _mongoc_gridfs_file_list_new_with_opts (mongoc_gridfs_t *gridfs, const bson_t *filter, const bson_t *opts); BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_LIST_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c0000664000175000017500000000613713210321137024405 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-collection-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-private.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_cursor_new (gridfs->client, gridfs->files->ns, MONGOC_QUERY_NONE, 0, limit, 0, false /* is command */, query, NULL, gridfs->files->read_prefs, gridfs->files->read_concern); BSON_ASSERT (cursor); list = (mongoc_gridfs_file_list_t *) bson_malloc0 (sizeof *list); list->cursor = cursor; list->gridfs = gridfs; return list; } mongoc_gridfs_file_list_t * _mongoc_gridfs_file_list_new_with_opts (mongoc_gridfs_t *gridfs, const bson_t *filter, const bson_t *opts) { mongoc_gridfs_file_list_t *list; mongoc_cursor_t *cursor; cursor = mongoc_collection_find_with_opts ( gridfs->files, filter, opts, NULL /* read prefs */); 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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h0000664000175000017500000000247413210321137024412 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-macros.h" #include "mongoc-gridfs-file.h" BSON_BEGIN_DECLS typedef struct _mongoc_gridfs_file_list_t mongoc_gridfs_file_list_t; MONGOC_EXPORT (mongoc_gridfs_file_t *) mongoc_gridfs_file_list_next (mongoc_gridfs_file_list_t *list); MONGOC_EXPORT (void) mongoc_gridfs_file_list_destroy (mongoc_gridfs_file_list_t *list); MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h0000664000175000017500000000421313210321137026014 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_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); uint32_t _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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c0000664000175000017500000001174613210321137024350 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-private.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: * Number of bytes set. */ uint32_t _mongoc_gridfs_file_page_memset0 (mongoc_gridfs_file_page_t *page, uint32_t len) { uint32_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 (bytes_set); } 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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h0000664000175000017500000000202613210321137024344 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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h0000664000175000017500000000344113210321137025104 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_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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file.c0000664000175000017500000006765213210321137023445 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-private.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) /** * mongoc_gridfs_file_set_id: * * the user can set the files_id to an id of any type. Must be called before * mongoc_gridfs_file_save. * */ bool mongoc_gridfs_file_set_id (mongoc_gridfs_file_t *file, const bson_value_t *id, bson_error_t *error) { if (!file->is_dirty) { bson_set_error (error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_PROTOCOL_ERROR, "Cannot set file id after saving file."); return false; } bson_value_copy (id, &file->files_id); return true; } /** 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_NUMBER (&iter)) { GOTO (failure); } file->length = bson_iter_as_int64 (&iter); } else if (0 == strcmp (key, "chunkSize")) { if (!BSON_ITER_HOLDS_NUMBER (&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 = ((int64_t) 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 * timeout_msec is unused */ 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); /* 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)) { return -1; } } } RETURN (bytes_read); } /** writev against a gridfs file * timeout_msec is unused */ ssize_t mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, const 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); /* 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 */ if (!_mongoc_gridfs_file_flush_page (file)) { return -1; } } } } 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); } } 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); } static int64_t divide_round_up (int64_t num, int64_t denom) { return (num + denom - 1) / denom; } static void missing_chunk (mongoc_gridfs_file_t *file) { bson_set_error (&file->error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_CHUNK_MISSING, "missing chunk number %" PRId32, file->n); if (file->cursor) { mongoc_cursor_destroy (file->cursor); file->cursor = NULL; } } /** * _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. If the position is far past the * end of the file, _mongoc_gridfs_file_extend is responsible for creating * chunks to file the gap. * * 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; bson_t child; bson_t opts; const bson_t *chunk; const char *key; bson_iter_t iter; int64_t existing_chunks; int64_t required_chunks; const uint8_t *data = NULL; 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), we'll pass the page constructor a new empty page. */ existing_chunks = divide_round_up (file->length, file->chunk_size); required_chunks = divide_round_up (file->pos + 1, file->chunk_size); if (required_chunks > existing_chunks) { 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) { bson_init (&query); BSON_APPEND_VALUE (&query, "files_id", &file->files_id); BSON_APPEND_DOCUMENT_BEGIN (&query, "n", &child); BSON_APPEND_INT32 (&child, "$gte", file->n); bson_append_document_end (&query, &child); bson_init (&opts); BSON_APPEND_DOCUMENT_BEGIN (&opts, "sort", &child); BSON_APPEND_INT32 (&child, "n", 1); bson_append_document_end (&opts, &child); BSON_APPEND_DOCUMENT_BEGIN (&opts, "projection", &child); BSON_APPEND_INT32 (&child, "n", 1); BSON_APPEND_INT32 (&child, "data", 1); BSON_APPEND_INT32 (&child, "_id", 0); bson_append_document_end (&opts, &child); /* find all chunks greater than or equal to our current file pos */ file->cursor = mongoc_collection_find_with_opts ( file->gridfs->chunks, &query, &opts, NULL); file->cursor_range[0] = file->n; file->cursor_range[1] = (uint32_t) (file->length / file->chunk_size); bson_destroy (&query); bson_destroy (&opts); 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 there's none, we're missing a chunk */ if (!mongoc_cursor_error (file->cursor, &file->error)) { missing_chunk (file); } 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)) { missing_chunk (file); 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; } } if (!data) { bson_set_error (&file->error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_CHUNK_MISSING, "corrupt chunk number %" PRId32, file->n); 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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-file.h0000664000175000017500000000721113210321137023433 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-macros.h" #include "mongoc-socket.h" BSON_BEGIN_DECLS #define MONGOC_GRIDFS_FILE_STR_HEADER(name) \ MONGOC_EXPORT (const char *) \ mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t *file); \ MONGOC_EXPORT (void) \ mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t *file, const char *str); #define MONGOC_GRIDFS_FILE_BSON_HEADER(name) \ MONGOC_EXPORT (const bson_t *) \ mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t *file); \ MONGOC_EXPORT (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) MONGOC_EXPORT (const bson_value_t *) mongoc_gridfs_file_get_id (mongoc_gridfs_file_t *file); MONGOC_EXPORT (int64_t) mongoc_gridfs_file_get_length (mongoc_gridfs_file_t *file); MONGOC_EXPORT (int32_t) mongoc_gridfs_file_get_chunk_size (mongoc_gridfs_file_t *file); MONGOC_EXPORT (int64_t) mongoc_gridfs_file_get_upload_date (mongoc_gridfs_file_t *file); MONGOC_EXPORT (ssize_t) mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, const mongoc_iovec_t *iov, size_t iovcnt, uint32_t timeout_msec); MONGOC_EXPORT (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); MONGOC_EXPORT (int) mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence); MONGOC_EXPORT (uint64_t) mongoc_gridfs_file_tell (mongoc_gridfs_file_t *file); MONGOC_EXPORT (bool) mongoc_gridfs_file_set_id (mongoc_gridfs_file_t *file, const bson_value_t *id, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_gridfs_file_save (mongoc_gridfs_file_t *file); MONGOC_EXPORT (void) mongoc_gridfs_file_destroy (mongoc_gridfs_file_t *file); MONGOC_EXPORT (bool) mongoc_gridfs_file_error (mongoc_gridfs_file_t *file, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-gridfs-private.h0000664000175000017500000000233313210321137024166 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_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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs.c0000664000175000017500000002742513210321137022522 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-private.h" #include "mongoc-cursor-private.h" #include "mongoc-util-private.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; /* mongoc_collection_create_index is deprecated, but works with MongoDB 2.4 * once we really drop 2.4, call "createIndexes" command directly */ BEGIN_IGNORE_DEPRECATIONS r = mongoc_collection_create_index (gridfs->chunks, &keys, &opt, error); END_IGNORE_DEPRECATIONS bson_destroy (&keys); if (!r) { RETURN (r); } bson_init (&keys); bson_append_int32 (&keys, "filename", -1, 1); bson_append_int32 (&keys, "uploadDate", -1, 1); opt.unique = 0; BEGIN_IGNORE_DEPRECATIONS r = mongoc_collection_create_index (gridfs->files, &keys, &opt, error); END_IGNORE_DEPRECATIONS 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; uint32_t prefix_len; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db); if (!prefix) { prefix = "fs"; } /* make sure prefix is short enough to bucket the chunks and files * collections */ prefix_len = (uint32_t) strlen (prefix); BSON_ASSERT (prefix_len + sizeof (".chunks") < sizeof (buf)); 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); if (!mongoc_gridfs_file_list_error (list, error) && error) { /* no error, but an error out-pointer was provided - clear it */ memset (error, 0, sizeof (*error)); } mongoc_gridfs_file_list_destroy (list); RETURN (file); } /** find all matching gridfs files */ mongoc_gridfs_file_list_t * mongoc_gridfs_find_with_opts (mongoc_gridfs_t *gridfs, const bson_t *filter, const bson_t *opts) { return _mongoc_gridfs_file_list_new_with_opts (gridfs, filter, opts); } /** find a single gridfs file */ mongoc_gridfs_file_t * mongoc_gridfs_find_one_with_opts (mongoc_gridfs_t *gridfs, const bson_t *filter, const bson_t *opts, bson_error_t *error) { mongoc_gridfs_file_list_t *list; mongoc_gridfs_file_t *file; bson_t new_opts; ENTRY; bson_init (&new_opts); if (opts) { bson_copy_to_excluding_noinit (opts, &new_opts, "limit", (char *) NULL); } BSON_APPEND_INT32 (&new_opts, "limit", 1); list = _mongoc_gridfs_file_list_new_with_opts (gridfs, filter, &new_opts); file = mongoc_gridfs_file_list_next (list); if (!mongoc_gridfs_file_list_error (list, error) && error) { /* no error, but an error out-pointer was provided - clear it */ memset (error, 0, sizeof (*error)); } mongoc_gridfs_file_list_destroy (list); bson_destroy (&new_opts); 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 filter; bson_init (&filter); bson_append_utf8 (&filter, "filename", -1, filename, -1); file = mongoc_gridfs_find_one_with_opts (gridfs, &filter, NULL, error); bson_destroy (&filter); 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_cursor_new (gridfs->client, gridfs->files->ns, MONGOC_QUERY_NONE, 0, 0, 0, false /* is command */, &q, &fields, NULL, 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.3.4/src/libmongoc/src/mongoc/mongoc-gridfs.h0000664000175000017500000000607013210321137022520 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-macros.h" #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_EXPORT (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_EXPORT (mongoc_gridfs_file_t *) mongoc_gridfs_create_file (mongoc_gridfs_t *gridfs, mongoc_gridfs_file_opt_t *opt); MONGOC_EXPORT (mongoc_gridfs_file_list_t *) mongoc_gridfs_find (mongoc_gridfs_t *gridfs, const bson_t *query) BSON_GNUC_DEPRECATED_FOR (mongoc_gridfs_find_with_opts); MONGOC_EXPORT (mongoc_gridfs_file_t *) mongoc_gridfs_find_one (mongoc_gridfs_t *gridfs, const bson_t *query, bson_error_t *error) BSON_GNUC_DEPRECATED_FOR (mongoc_gridfs_find_one_with_opts); MONGOC_EXPORT (mongoc_gridfs_file_list_t *) mongoc_gridfs_find_with_opts (mongoc_gridfs_t *gridfs, const bson_t *filter, const bson_t *opts) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (mongoc_gridfs_file_t *) mongoc_gridfs_find_one_with_opts (mongoc_gridfs_t *gridfs, const bson_t *filter, const bson_t *opts, bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (mongoc_gridfs_file_t *) mongoc_gridfs_find_one_by_filename (mongoc_gridfs_t *gridfs, const char *filename, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_gridfs_drop (mongoc_gridfs_t *gridfs, bson_error_t *error); MONGOC_EXPORT (void) mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs); MONGOC_EXPORT (mongoc_collection_t *) mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs); MONGOC_EXPORT (mongoc_collection_t *) mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs); MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-gssapi-private.h0000664000175000017500000000177213210321137024204 0ustar jmikolajmikola/* * Copyright 2017 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_GSSAPI_PRIVATE_H #define MONGOC_GSSAPI_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-sasl-private.h" BSON_BEGIN_DECLS typedef struct _mongoc_gssapi_t mongoc_gssapi_t; struct _mongoc_gssapi_t { mongoc_sasl_t credentials; bool done; int step; }; BSON_END_DECLS #endif /* MONGOC_GSSAPI_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-gssapi.c0000664000175000017500000000144613210321137022525 0ustar jmikolajmikola/* * Copyright 2017 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_GSSAPI #include "mongoc-gssapi-private.h" #include "mongoc-trace-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "GSSAPI" /* ... */ #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-handshake-compiler-private.h0000664000175000017500000000444213210321137026451 0ustar jmikolajmikola/* * Copyright 2016 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_HANDSHAKE_COMPILER_PRIVATE_H #define MONGOC_HANDSHAKE_COMPILER_PRIVATE_H #include "mongoc-config.h" #include "mongoc-util-private.h" /* * Thanks to: * http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros */ #if defined(__clang__) #define MONGOC_COMPILER "clang" #define MONGOC_COMPILER_VERSION __clang_version__ #elif defined(__ICC) || defined(__INTEL_COMPILER) #define MONGOC_COMPILER "ICC" #define MONGOC_COMPILER_VERSION __VERSION__ #elif defined(__GNUC__) || defined(__GNUG__) #define MONGOC_COMPILER "GCC" #define MONGOC_COMPILER_VERSION __VERSION__ #elif defined(__HP_cc) || defined(__HP_aCC) #define MONGOC_COMPILER "aCC" #define MONGOC_COMPILER_VERSION MONGOC_EVALUATE_STR (__HP_cc) #elif defined(__IBMC__) || defined(__IBMCPP__) #define MONGOC_COMPILER "xlc" #define MONGOC_COMPILER_VERSION __xlc__ #elif defined(_MSC_VER) #define MONGOC_COMPILER "MSVC" #define MONGOC_COMPILER_VERSION MONGOC_EVALUATE_STR (_MSC_VER) #elif defined(__PGI) #define MONGOC_COMPILER "Portland PGCC" #define MONGOC_COMPILER_VERSION \ MONGOC_EVALUATE_STR (__PGIC__) \ "." MONGOC_EVALUATE_STR (__PGIC_MINOR) "." MONGOC_EVALUATE_STR ( \ __PGIC_PATCHLEVEL__) #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) #define MONGOC_COMPILER "Solaris Studio" #define MONGOC_COMPILER_VERSION MONGOC_EVALUATE_STR (__SUNPRO_C) #elif defined(__PCC__) /* Portable C Compiler. Version may not be available */ #define MONGOC_COMPILER "PCC" #else #define MONGOC_COMPILER MONGOC_EVALUATE_STR (MONGOC_CC) /* Not defining COMPILER_VERSION. We'll fall back to values set at * configure-time */ #endif #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-handshake-os-private.h0000664000175000017500000000533713210321137025264 0ustar jmikolajmikola/* * Copyright 2016 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_HANDSHAKE_OS_PRIVATE #define MONGOC_HANDSHAKE_OS_PRIVATE /* Based on tables from * http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system */ #if defined(_WIN32) || defined(__CYGWIN__) #define MONGOC_OS_TYPE "Windows" #if defined(__CYGWIN__) #define MONGOC_OS_NAME "Cygwin" #else #define MONGOC_OS_NAME "Windows" #endif /* osx and iphone defines __APPLE__ and __MACH__, but not __unix__ */ #elif defined(__APPLE__) && defined(__MACH__) && !defined(__unix__) #define MONGOC_OS_TYPE "Darwin" #include #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR == 1 #define MONGOC_OS_NAME "iOS Simulator" #elif defined(TARGET_OS_IOS) && TARGET_OS_IOS == 1 #define MONGOC_OS_NAME "iOS" #elif defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1 #define MONGOC_OS_NAME "macOS" #elif defined(TARGET_OS_TV) && TARGET_OS_TV == 1 #define MONGOC_OS_NAME "tvOS" #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 #define MONGOC_OS_NAME "watchOS" #else /* Fall back to uname () */ #endif /* Need to check if __unix is defined since sun and hpux always have __unix, * but not necessarily __unix__ defined. */ #elif defined(__unix__) || defined(__unix) #include #if defined(__linux__) #define MONGOC_OS_IS_LINUX #if defined(__ANDROID__) #define MONGOC_OS_TYPE "Linux (Android)" #else #define MONGOC_OS_TYPE "Linux" #endif /* Don't define OS_NAME. We'll scan the file system to determine distro. */ #elif defined(BSD) #define MONGOC_OS_TYPE "BSD" #if defined(__FreeBSD__) #define MONGOC_OS_NAME "FreeBSD" #elif defined(__NetBSD__) #define MONGOC_OS_NAME "NetBSD" #elif defined(__OpenBSD__) #define MONGOC_OS_NAME "OpenBSD" #elif defined(__DragonFly__) #define MONGOC_OS_NAME "DragonFlyBSD" #else /* Don't define OS_NAME. We'll use uname to figure it out. */ #endif #else #define MONGOC_OS_TYPE "Unix" #if defined(_AIX) #define MONGOC_OS_NAME "AIX" #elif defined(__sun) && defined(__SVR4) #define MONGOC_OS_NAME "Solaris" #elif defined(__hpux) #define MONGOC_OS_NAME "HP-UX" #else /* Don't set OS name. We'll just fall back to uname. */ #endif #endif #endif #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-handshake-private.h0000664000175000017500000000600213210321137024633 0ustar jmikolajmikola/* * Copyright 2016 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_HANDSHAKE_PRIVATE_H #define MONGOC_HANDSHAKE_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include BSON_BEGIN_DECLS #define HANDSHAKE_FIELD "client" #define HANDSHAKE_PLATFORM_FIELD "platform" #define HANDSHAKE_MAX_SIZE 512 #define HANDSHAKE_OS_TYPE_MAX 32 #define HANDSHAKE_OS_NAME_MAX 32 #define HANDSHAKE_OS_VERSION_MAX 32 #define HANDSHAKE_OS_ARCHITECTURE_MAX 32 #define HANDSHAKE_DRIVER_NAME_MAX 64 #define HANDSHAKE_DRIVER_VERSION_MAX 32 /* platform has no fixed max size. It can just occupy the remaining * available space in the document. */ /* When adding a new field to mongoc-config.h.in, update this! */ typedef enum { MONGOC_MD_FLAG_ENABLE_CRYPTO = 1 << 0, MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG = 1 << 1, MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO = 1 << 2, MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO = 1 << 3, MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE = 1 << 4, MONGOC_MD_FLAG_ENABLE_SASL = 1 << 5, MONGOC_MD_FLAG_ENABLE_SSL = 1 << 6, MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL = 1 << 7, MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL = 1 << 8, MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT = 1 << 9, MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES = 1 << 10, MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE = 1 << 11, MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS = 1 << 12, MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS = 1 << 13, MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL = 1 << 14, MONGOC_MD_FLAG_ENABLE_SASL_CYRUS = 1 << 15, MONGOC_MD_FLAG_ENABLE_SASL_SSPI = 1 << 16, MONGOC_MD_FLAG_HAVE_SOCKLEN = 1 << 17, MONGOC_MD_FLAG_ENABLE_COMPRESSION = 1 << 18, MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY = 1 << 19, MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB = 1 << 20, MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI = 1 << 21, } mongoc_handshake_config_flags_t; typedef struct _mongoc_handshake_t { char *os_type; char *os_name; char *os_version; char *os_architecture; char *driver_name; char *driver_version; char *platform; bool frozen; } mongoc_handshake_t; void _mongoc_handshake_init (void); void _mongoc_handshake_cleanup (void); bool _mongoc_handshake_build_doc_with_application (bson_t *doc, const char *application); void _mongoc_handshake_freeze (void); mongoc_handshake_t * _mongoc_handshake_get (void); bool _mongoc_handshake_appname_is_valid (const char *appname); BSON_END_DECLS #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-handshake.c0000664000175000017500000003205313210321137023163 0ustar jmikolajmikola/* * Copyright 2016 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 #ifdef _POSIX_VERSION #include #endif #ifdef _WIN32 #include #endif #include "mongoc-linux-distro-scanner-private.h" #include "mongoc-handshake.h" #include "mongoc-handshake-compiler-private.h" #include "mongoc-handshake-os-private.h" #include "mongoc-handshake-private.h" #include "mongoc-client.h" #include "mongoc-client-private.h" #include "mongoc-error.h" #include "mongoc-log.h" #include "mongoc-version.h" #include "mongoc-util-private.h" /* * Global handshake data instance. Initialized at startup from mongoc_init () * * Can be modified by calls to mongoc_handshake_data_append () */ static mongoc_handshake_t gMongocHandshake; static uint32_t _get_config_bitfield (void) { uint32_t bf = 0; #ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL bf |= MONGOC_MD_FLAG_ENABLE_SSL_SECURE_CHANNEL; #endif #ifdef MONGOC_ENABLE_CRYPTO_CNG bf |= MONGOC_MD_FLAG_ENABLE_CRYPTO_CNG; #endif #ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT bf |= MONGOC_MD_FLAG_ENABLE_SSL_SECURE_TRANSPORT; #endif #ifdef MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO bf |= MONGOC_MD_FLAG_ENABLE_CRYPTO_COMMON_CRYPTO; #endif #ifdef MONGOC_ENABLE_SSL_OPENSSL bf |= MONGOC_MD_FLAG_ENABLE_SSL_OPENSSL; #endif #ifdef MONGOC_ENABLE_CRYPTO_LIBCRYPTO bf |= MONGOC_MD_FLAG_ENABLE_CRYPTO_LIBCRYPTO; #endif #ifdef MONGOC_ENABLE_SSL bf |= MONGOC_MD_FLAG_ENABLE_SSL; #endif #ifdef MONGOC_ENABLE_CRYPTO bf |= MONGOC_MD_FLAG_ENABLE_CRYPTO; #endif #ifdef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE bf |= MONGOC_MD_FLAG_ENABLE_CRYPTO_SYSTEM_PROFILE; #endif #ifdef MONGOC_ENABLE_SASL bf |= MONGOC_MD_FLAG_ENABLE_SASL; #endif #ifdef MONGOC_HAVE_SASL_CLIENT_DONE bf |= MONGOC_MD_FLAG_HAVE_SASL_CLIENT_DONE; #endif #ifdef MONGOC_HAVE_WEAK_SYMBOLS bf |= MONGOC_MD_FLAG_HAVE_WEAK_SYMBOLS; #endif #ifdef MONGOC_NO_AUTOMATIC_GLOBALS bf |= MONGOC_MD_FLAG_NO_AUTOMATIC_GLOBALS; #endif #ifdef MONGOC_EXPERIMENTAL_FEATURES bf |= MONGOC_MD_FLAG_EXPERIMENTAL_FEATURES; #endif #ifdef MONGOC_ENABLE_SSL_LIBRESSL bf |= MONGOC_MD_FLAG_ENABLE_SSL_LIBRESSL; #endif #ifdef MONGOC_ENABLE_SASL_CYRUS bf |= MONGOC_MD_FLAG_ENABLE_SASL_CYRUS; #endif #ifdef MONGOC_ENABLE_SASL_SSPI bf |= MONGOC_MD_FLAG_ENABLE_SASL_SSPI; #endif #ifdef MONGOC_HAVE_SOCKLEN bf |= MONGOC_MD_FLAG_HAVE_SOCKLEN; #endif #ifdef MONGOC_ENABLE_COMPRESSION bf |= MONGOC_MD_FLAG_ENABLE_COMPRESSION; #endif #ifdef MONGOC_ENABLE_COMPRESSION_SNAPPY bf |= MONGOC_MD_FLAG_ENABLE_COMPRESSION_SNAPPY; #endif #ifdef MONGOC_ENABLE_COMPRESSION_ZLIB bf |= MONGOC_MD_FLAG_ENABLE_COMPRESSION_ZLIB; #endif #ifdef MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI bf |= MONGOC_MD_FLAG_ENABLE_SASL_GSSAPI; #endif return bf; } static char * _get_os_type (void) { #ifdef MONGOC_OS_TYPE return bson_strndup (MONGOC_OS_TYPE, HANDSHAKE_OS_TYPE_MAX); #else return bson_strndup ("unknown", HANDSHAKE_OS_TYPE_MAX); #endif } static char * _get_os_architecture (void) { const char *ret = NULL; #ifdef _WIN32 SYSTEM_INFO system_info; DWORD arch; GetSystemInfo (&system_info); arch = system_info.wProcessorArchitecture; switch (arch) { case PROCESSOR_ARCHITECTURE_AMD64: ret = "x86_64"; break; case PROCESSOR_ARCHITECTURE_ARM: ret = "ARM"; break; case PROCESSOR_ARCHITECTURE_IA64: ret = "IA64"; break; case PROCESSOR_ARCHITECTURE_INTEL: ret = "x86"; break; case PROCESSOR_ARCHITECTURE_UNKNOWN: ret = "Unknown"; break; default: ret = "Other"; break; } #elif defined(_POSIX_VERSION) struct utsname system_info; if (uname (&system_info) >= 0) { ret = system_info.machine; } #endif if (ret) { return bson_strndup (ret, HANDSHAKE_OS_ARCHITECTURE_MAX); } return NULL; } #ifndef MONGOC_OS_IS_LINUX static char * _get_os_name (void) { #ifdef MONGOC_OS_NAME return bson_strndup (MONGOC_OS_NAME, HANDSHAKE_OS_NAME_MAX); #elif defined(_POSIX_VERSION) struct utsname system_info; if (uname (&system_info) >= 0) { return bson_strndup (system_info.sysname, HANDSHAKE_OS_NAME_MAX); } #endif return NULL; } static char * _get_os_version (void) { char *ret = bson_malloc (HANDSHAKE_OS_VERSION_MAX); bool found = false; #ifdef _WIN32 OSVERSIONINFO osvi; ZeroMemory (&osvi, sizeof (OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (GetVersionEx (&osvi)) { bson_snprintf (ret, HANDSHAKE_OS_VERSION_MAX, "%lu.%lu (%lu)", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); found = true; } else { MONGOC_WARNING ("Error with GetVersionEx(): %lu", GetLastError ()); } #elif defined(_POSIX_VERSION) struct utsname system_info; if (uname (&system_info) >= 0) { bson_strncpy (ret, system_info.release, HANDSHAKE_OS_VERSION_MAX); found = true; } else { MONGOC_WARNING ("Error with uname(): %d", errno); } #endif if (!found) { bson_free (ret); ret = NULL; } return ret; } #endif static void _get_system_info (mongoc_handshake_t *handshake) { handshake->os_type = _get_os_type (); #ifdef MONGOC_OS_IS_LINUX _mongoc_linux_distro_scanner_get_distro (&handshake->os_name, &handshake->os_version); #else handshake->os_name = _get_os_name (); handshake->os_version = _get_os_version (); #endif handshake->os_architecture = _get_os_architecture (); } static void _free_system_info (mongoc_handshake_t *handshake) { bson_free (handshake->os_type); bson_free (handshake->os_name); bson_free (handshake->os_version); bson_free (handshake->os_architecture); } static void _get_driver_info (mongoc_handshake_t *handshake) { handshake->driver_name = bson_strndup ("mongoc", HANDSHAKE_DRIVER_NAME_MAX); handshake->driver_version = bson_strndup (MONGOC_VERSION_S, HANDSHAKE_DRIVER_VERSION_MAX); } static void _free_driver_info (mongoc_handshake_t *handshake) { bson_free (handshake->driver_name); bson_free (handshake->driver_version); } static void _set_platform_string (mongoc_handshake_t *handshake) { bson_string_t *str; str = bson_string_new (""); bson_string_append_printf (str, "cfg=0x%x", _get_config_bitfield ()); #ifdef _POSIX_VERSION bson_string_append_printf (str, " posix=%ld", _POSIX_VERSION); #endif #ifdef __STDC_VERSION__ bson_string_append_printf (str, " stdc=%ld", __STDC_VERSION__); #endif bson_string_append_printf (str, " CC=%s", MONGOC_COMPILER); #ifdef MONGOC_COMPILER_VERSION bson_string_append_printf (str, " %s", MONGOC_COMPILER_VERSION); #endif if (strlen (MONGOC_EVALUATE_STR (MONGOC_USER_SET_CFLAGS)) > 0) { bson_string_append_printf ( str, " CFLAGS=%s", MONGOC_EVALUATE_STR (MONGOC_USER_SET_CFLAGS)); } if (strlen (MONGOC_EVALUATE_STR (MONGOC_USER_SET_LDFLAGS)) > 0) { bson_string_append_printf ( str, " LDFLAGS=%s", MONGOC_EVALUATE_STR (MONGOC_USER_SET_LDFLAGS)); } handshake->platform = bson_string_free (str, false); } static void _free_platform_string (mongoc_handshake_t *handshake) { bson_free (handshake->platform); } void _mongoc_handshake_init (void) { _get_system_info (_mongoc_handshake_get ()); _get_driver_info (_mongoc_handshake_get ()); _set_platform_string (_mongoc_handshake_get ()); _mongoc_handshake_get ()->frozen = false; } void _mongoc_handshake_cleanup (void) { _free_system_info (_mongoc_handshake_get ()); _free_driver_info (_mongoc_handshake_get ()); _free_platform_string (_mongoc_handshake_get ()); } static bool _append_platform_field (bson_t *doc, const char *platform) { int max_platform_str_size; /* Compute space left for platform field */ max_platform_str_size = HANDSHAKE_MAX_SIZE - (doc->len + /* 1 byte for utf8 tag */ 1 + /* key size */ strlen (HANDSHAKE_PLATFORM_FIELD) + 1 + /* 4 bytes for length of string */ 4); if (max_platform_str_size <= 0) { return false; } max_platform_str_size = BSON_MIN (max_platform_str_size, strlen (platform) + 1); bson_append_utf8 ( doc, HANDSHAKE_PLATFORM_FIELD, -1, platform, max_platform_str_size - 1); BSON_ASSERT (doc->len <= HANDSHAKE_MAX_SIZE); return true; } /* * Return true if we build the document, and it's not too big * false if there's no way to prevent the doc from being too big. In this * case, the caller shouldn't include it with isMaster */ bool _mongoc_handshake_build_doc_with_application (bson_t *doc, const char *appname) { const mongoc_handshake_t *md = _mongoc_handshake_get (); bson_t child; if (appname) { BSON_APPEND_DOCUMENT_BEGIN (doc, "application", &child); BSON_APPEND_UTF8 (&child, "name", appname); bson_append_document_end (doc, &child); } BSON_APPEND_DOCUMENT_BEGIN (doc, "driver", &child); BSON_APPEND_UTF8 (&child, "name", md->driver_name); BSON_APPEND_UTF8 (&child, "version", md->driver_version); bson_append_document_end (doc, &child); BSON_APPEND_DOCUMENT_BEGIN (doc, "os", &child); BSON_ASSERT (md->os_type); BSON_APPEND_UTF8 (&child, "type", md->os_type); if (md->os_name) { BSON_APPEND_UTF8 (&child, "name", md->os_name); } if (md->os_version) { BSON_APPEND_UTF8 (&child, "version", md->os_version); } if (md->os_architecture) { BSON_APPEND_UTF8 (&child, "architecture", md->os_architecture); } bson_append_document_end (doc, &child); if (doc->len > HANDSHAKE_MAX_SIZE) { /* We've done all we can possibly do to ensure the current * document is below the maxsize, so if it overflows there is * nothing else we can do, so we fail */ return false; } if (md->platform) { _append_platform_field (doc, md->platform); } return true; } void _mongoc_handshake_freeze (void) { _mongoc_handshake_get ()->frozen = true; } /* * free (*s) and make *s point to *s concated with suffix. * If *s is NULL it's treated like it's an empty string. * If suffix is NULL, nothing happens. */ static void _append_and_truncate (char **s, const char *suffix, int max_len) { char *old_str = *s; char *prefix; const int delim_len = strlen (" / "); int space_for_suffix; BSON_ASSERT (s); prefix = old_str ? old_str : ""; if (!suffix) { return; } space_for_suffix = max_len - strlen (prefix) - delim_len; BSON_ASSERT (space_for_suffix >= 0); *s = bson_strdup_printf ("%s / %.*s", prefix, space_for_suffix, suffix); BSON_ASSERT (strlen (*s) <= max_len); bson_free (old_str); } /* * Set some values in our global handshake struct. These values will be sent * to the server as part of the initial connection handshake (isMaster). * If this function is called more than once, or after we've connected to a * mongod, then it will do nothing and return false. It will return true if it * successfully sets the values. * * All arguments are optional. */ bool mongoc_handshake_data_append (const char *driver_name, const char *driver_version, const char *platform) { int max_size = 0; if (_mongoc_handshake_get ()->frozen) { MONGOC_ERROR ("Cannot set handshake more than once"); return false; } _append_and_truncate (&_mongoc_handshake_get ()->driver_name, driver_name, HANDSHAKE_DRIVER_NAME_MAX); _append_and_truncate (&_mongoc_handshake_get ()->driver_version, driver_version, HANDSHAKE_DRIVER_VERSION_MAX); max_size = HANDSHAKE_MAX_SIZE - -_mongoc_strlen_or_zero (_mongoc_handshake_get ()->os_type) - _mongoc_strlen_or_zero (_mongoc_handshake_get ()->os_name) - _mongoc_strlen_or_zero (_mongoc_handshake_get ()->os_version) - _mongoc_strlen_or_zero (_mongoc_handshake_get ()->os_architecture) - _mongoc_strlen_or_zero (_mongoc_handshake_get ()->driver_name) - _mongoc_strlen_or_zero (_mongoc_handshake_get ()->driver_version); _append_and_truncate ( &_mongoc_handshake_get ()->platform, platform, max_size); _mongoc_handshake_freeze (); return true; } mongoc_handshake_t * _mongoc_handshake_get (void) { return &gMongocHandshake; } bool _mongoc_handshake_appname_is_valid (const char *appname) { return strlen (appname) <= MONGOC_HANDSHAKE_APPNAME_MAX; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-handshake.h0000664000175000017500000000623113210321137023167 0ustar jmikolajmikola/* * Copyright 2016 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_HANDSHAKE_H #define MONGOC_HANDSHAKE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-macros.h" BSON_BEGIN_DECLS #define MONGOC_HANDSHAKE_APPNAME_MAX 128 /** * mongoc_handshake_data_append: * * This function is intended for use by drivers which wrap the C Driver. * Calling this function will store the given strings as handshake data about * the system and driver by appending them to the handshake data for the * underlying C Driver. These values, along with other handshake data collected * during mongoc_init will be sent to the server as part of the initial * connection handshake in the "client" document. This function cannot be * called more than once, or after a handshake has been initiated. * * The passed in strings are copied, and don't have to remain valid after the * call to mongoc_handshake_data_append(). The driver may store truncated * versions of the passed in strings. * * Note: * This function allocates memory, and therefore caution should be used when * using this in conjunction with bson_mem_set_vtable. If this function is * called before bson_mem_set_vtable, then bson_mem_restore_vtable must be * called before calling mongoc_cleanup. Failure to do so will result in * memory being freed by the wrong allocator. * * * @driver_name: An optional string storing the name of the wrapping driver * @driver_version: An optional string storing the version of the wrapping * driver. * @platform: An optional string storing any information about the current * platform, for example configure options or compile flags. * * * Returns true if the given fields are set successfully. Otherwise, it returns * false and logs an error. * * The default handshake data the driver sends with "isMaster" looks something * like: * client: { * driver: { * name: "mongoc", * version: "1.5.0" * }, * os: {...}, * platform: "CC=gcc CFLAGS=-Wall -pedantic" * } * * If we call * mongoc_handshake_data_append ("phongo", "1.1.8", "CC=clang") * and it returns true, the driver sends handshake data like: * client: { * driver: { * name: "mongoc / phongo", * version: "1.5.0 / 1.1.8" * }, * os: {...}, * platform: "CC=gcc CFLAGS=-Wall -pedantic / CC=clang" * } * */ MONGOC_EXPORT (bool) mongoc_handshake_data_append (const char *driver_name, const char *driver_version, const char *platform); BSON_END_DECLS #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-host-list-private.h0000664000175000017500000000223713210321137024641 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_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.3.4/src/libmongoc/src/mongoc/mongoc-host-list.c0000664000175000017500000001100213210321137023152 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; } } /* *-------------------------------------------------------------------------- * * _mongoc_host_list_from_string -- * * Populate a mongoc_host_list_t from a fully qualified address * *-------------------------------------------------------------------------- */ bool _mongoc_host_list_from_string (mongoc_host_list_t *link_, const char *address) { char *close_bracket; bool bracket_at_end; char *sport; uint16_t port; if (*address == '\0') { MONGOC_ERROR ("empty address in _mongoc_host_list_from_string"); BSON_ASSERT (false); } close_bracket = strchr (address, ']'); bracket_at_end = close_bracket && *(close_bracket + 1) == '\0'; sport = strrchr (address, ':'); if (sport < close_bracket || (close_bracket && sport != close_bracket + 1)) { /* ignore colons within IPv6 address like "[fe80::1]" */ sport = NULL; } /* like "example.com:27019" or "[fe80::1]:27019", but not "[fe80::1]" */ if (sport) { if (!mongoc_parse_port (&port, sport + 1)) { return false; } link_->port = port; } else { link_->port = MONGOC_DEFAULT_PORT; } /* like "[fe80::1]:27019" or ""[fe80::1]" */ if (*address == '[' && (bracket_at_end || (close_bracket && sport))) { link_->family = AF_INET6; bson_strncpy (link_->host, address + 1, BSON_MIN (close_bracket - address, sizeof link_->host)); mongoc_lowercase (link_->host, link_->host); bson_snprintf (link_->host_and_port, sizeof link_->host_and_port, "[%s]:%hu", link_->host, link_->port); } else if (strchr (address, '/') && strstr (address, ".sock")) { link_->family = AF_UNIX; if (sport) { /* weird: "/tmp/mongodb.sock:1234", ignore the port number */ bson_strncpy (link_->host, address, BSON_MIN (sport - address + 1, sizeof link_->host)); } else { bson_strncpy (link_->host, address, sizeof link_->host); } bson_strncpy ( link_->host_and_port, link_->host, sizeof link_->host_and_port); } else if (sport == address) { /* bad address like ":27017" */ return false; } else { link_->family = AF_INET; if (sport) { bson_strncpy (link_->host, address, BSON_MIN (sport - address + 1, sizeof link_->host)); } else { bson_strncpy (link_->host, address, sizeof link_->host); } mongoc_lowercase (link_->host, link_->host); bson_snprintf (link_->host_and_port, sizeof link_->host_and_port, "%s:%hu", link_->host, link_->port); } link_->next = NULL; return true; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-host-list.h0000664000175000017500000000232613210321137023170 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 #ifdef _POSIX_HOST_NAME_MAX #define BSON_HOST_NAME_MAX _POSIX_HOST_NAME_MAX #else #define BSON_HOST_NAME_MAX 255 #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.3.4/src/libmongoc/src/mongoc/mongoc-index.c0000664000175000017500000000501713210321137022344 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-private.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, /* collation */ {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.3.4/src/libmongoc/src/mongoc/mongoc-index.h0000664000175000017500000000455713210321137022361 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 #include "mongoc-macros.h" 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; const bson_t *collation; void *padding[4]; } mongoc_index_opt_t; MONGOC_EXPORT (const mongoc_index_opt_t *) mongoc_index_opt_get_default (void) BSON_GNUC_CONST; MONGOC_EXPORT (const mongoc_index_opt_geo_t *) mongoc_index_opt_geo_get_default (void) BSON_GNUC_CONST; MONGOC_EXPORT (const mongoc_index_opt_wt_t *) mongoc_index_opt_wt_get_default (void) BSON_GNUC_CONST; MONGOC_EXPORT (void) mongoc_index_opt_init (mongoc_index_opt_t *opt); MONGOC_EXPORT (void) mongoc_index_opt_geo_init (mongoc_index_opt_geo_t *opt); MONGOC_EXPORT (void) mongoc_index_opt_wt_init (mongoc_index_opt_wt_t *opt); BSON_END_DECLS #endif /* MONGOC_INDEX_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-init.c0000664000175000017500000001044413210321137022200 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" #include "mongoc-handshake-private.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-scram-private.h" #include "mongoc-ssl.h" #ifdef MONGOC_ENABLE_SSL_OPENSSL #include "mongoc-openssl-private.h" #elif defined(MONGOC_ENABLE_SSL_LIBRESSL) #include "tls.h" #endif #endif #include "mongoc-thread-private.h" #include "mongoc-trace-private.h" #ifndef MONGOC_NO_AUTOMATIC_GLOBALS #pragma message( \ "Configure the driver with --disable-automatic-init-and-cleanup\ (if using ./configure) or ENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF (with cmake).\ Automatic cleanup is deprecated and will be removed in version 2.0.") #endif #ifdef MONGOC_ENABLE_SASL_CYRUS #include #include "mongoc-cyrus-private.h" static void * mongoc_cyrus_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_cyrus_mutex_lock (void *mutex) { mongoc_mutex_lock ((mongoc_mutex_t *) mutex); return SASL_OK; } static int mongoc_cyrus_mutex_unlock (void *mutex) { mongoc_mutex_unlock ((mongoc_mutex_t *) mutex); return SASL_OK; } static void mongoc_cyrus_mutex_free (void *mutex) { mongoc_mutex_destroy ((mongoc_mutex_t *) mutex); bson_free (mutex); } #endif /* MONGOC_ENABLE_SASL_CYRUS */ static MONGOC_ONCE_FUN (_mongoc_do_init) { #ifdef MONGOC_ENABLE_SASL_CYRUS int status; sasl_callback_t callbacks[] = { {SASL_CB_LOG, SASL_CALLBACK_FN (_mongoc_cyrus_log), NULL}, {SASL_CB_LIST_END}}; #endif #ifdef MONGOC_ENABLE_SSL_OPENSSL _mongoc_openssl_init (); #elif defined(MONGOC_ENABLE_SSL_LIBRESSL) tls_init (); #endif #ifdef MONGOC_ENABLE_SSL _mongoc_scram_startup (); #endif #ifdef MONGOC_ENABLE_SASL_CYRUS /* The following functions should not use tracing, as they may be invoked * before mongoc_log_set_handler() can complete. */ sasl_set_mutex (mongoc_cyrus_mutex_alloc, mongoc_cyrus_mutex_lock, mongoc_cyrus_mutex_unlock, mongoc_cyrus_mutex_free); status = sasl_client_init (callbacks); BSON_ASSERT (status == SASL_OK); #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_handshake_init (); 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_OPENSSL _mongoc_openssl_cleanup (); #endif #ifdef MONGOC_ENABLE_SASL_CYRUS #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_handshake_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) { bson_mem_restore_vtable (); mongoc_cleanup (); } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-init.h0000664000175000017500000000167513210321137022213 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 #include "mongoc-macros.h" BSON_BEGIN_DECLS MONGOC_EXPORT (void) mongoc_init (void); MONGOC_EXPORT (void) mongoc_cleanup (void); BSON_END_DECLS #endif /* MONGOC_INIT_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-iovec.h0000664000175000017500000000227213210321137022347 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.3.4/src/libmongoc/src/mongoc/mongoc-libressl-private.h0000664000175000017500000000226313210321137024531 0ustar jmikolajmikola/* * Copyright 2016 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_LIBRESSL_PRIVATE_H #define MONGOC_LIBRESSL_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-ssl.h" #include "mongoc-stream-tls-libressl-private.h" #include BSON_BEGIN_DECLS bool mongoc_libressl_setup_ca (mongoc_stream_tls_libressl_t *libressl, mongoc_ssl_opt_t *opt); bool mongoc_libressl_setup_certificate (mongoc_stream_tls_libressl_t *libressl, mongoc_ssl_opt_t *opt); BSON_END_DECLS #endif /* MONGOC_LIBRESSL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-libressl.c0000664000175000017500000000355013210321137023054 0ustar jmikolajmikola/* * Copyright 2016 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_LIBRESSL #include #include "mongoc-log.h" #include "mongoc-trace-private.h" #include "mongoc-ssl.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-tls-private.h" #include "mongoc-libressl-private.h" #include "mongoc-stream-tls-libressl-private.h" #include #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-libressl" bool mongoc_libressl_setup_certificate (mongoc_stream_tls_libressl_t *libressl, mongoc_ssl_opt_t *opt) { uint8_t *file; size_t file_len; if (!opt->pem_file) { return false; } file = tls_load_file (opt->pem_file, &file_len, (char *) opt->pem_pwd); if (!file) { return false; } if (tls_config_set_keypair_mem ( libressl->config, file, file_len, file, file_len) == -1) { MONGOC_ERROR ("%s", tls_config_error (libressl->config)); return false; } return true; } bool mongoc_libressl_setup_ca (mongoc_stream_tls_libressl_t *libressl, mongoc_ssl_opt_t *opt) { if (opt->ca_file) { tls_config_set_ca_file (libressl->config, opt->ca_file); } if (opt->ca_dir) { tls_config_set_ca_path (libressl->config, opt->ca_dir); } return true; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner-private.h0000664000175000017500000000363613210321137027007 0ustar jmikolajmikola/* * Copyright 2016 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_LINUX_DISTRO_SCANNER_PRIVATE_H #define MONGOC_LINUX_DISTRO_SCANNER_PRIVATE_H #include "mongoc-handshake-os-private.h" #ifdef MONGOC_OS_IS_LINUX BSON_BEGIN_DECLS bool _mongoc_linux_distro_scanner_get_distro (char **name, char **version); /* These functions are exposed so we can test them separately. */ void _mongoc_linux_distro_scanner_read_key_value_file (const char *path, const char *name_key, ssize_t name_key_len, char **name, const char *version_key, ssize_t version_key_len, char **version); void _mongoc_linux_distro_scanner_read_generic_release_file (const char **paths, char **name, char **version); void _mongoc_linux_distro_scanner_split_line_by_release (const char *line, ssize_t line_len, char **name, char **version); BSON_END_DECLS #endif #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-linux-distro-scanner.c0000664000175000017500000002557113210321137025334 0ustar jmikolajmikola/* * Copyright 2016 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-handshake-os-private.h" #ifdef MONGOC_OS_IS_LINUX #include #include #include "mongoc-error.h" #include "mongoc-linux-distro-scanner-private.h" #include "mongoc-log.h" #include "mongoc-handshake-private.h" #include "mongoc-trace-private.h" #include "mongoc-util-private.h" #include "mongoc-version.h" #define LINE_BUFFER_SIZE 1024 /* * fgets() wrapper which removes '\n' at the end of the string * Return 0 on failure or EOF. */ static size_t _fgets_wrapper (char *buffer, size_t buffer_size, FILE *f) { char *fgets_res; size_t len; fgets_res = fgets (buffer, buffer_size, f); if (!fgets_res) { /* Didn't read anything. Empty file or error. */ if (ferror (f)) { TRACE ("fgets() failed with error %d", errno); } return 0; } /* Chop off trailing \n */ len = strlen (buffer); if (len > 0 && buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; len--; } else if (len == buffer_size - 1) { /* We read buffer_size bytes without hitting a newline * therefore the line is super long, so we say this file is invalid. * This is important since if we are in this situation, the NEXT call to * fgets() will keep reading where we left off. * * This protects us from files like: * aaaaa...DISTRIB_ID=nasal demons */ TRACE ("Found line of length %ld, bailing out", len); return 0; } return len; } static void _process_line (const char *name_key, size_t name_key_len, char **name, const char *version_key, size_t version_key_len, char **version, const char *line, size_t line_len) { size_t key_len; const char *equal_sign; const char *value; const char *needle = "="; size_t value_len = 0; ENTRY; /* Figure out where = is. Everything before is the key, * and everything after is the value */ equal_sign = strstr (line, needle); if (equal_sign == NULL) { TRACE ("Encountered malformed line: %s", line); /* This line is malformed/incomplete, so skip it */ EXIT; } /* Should never happen since we null terminated this line */ BSON_ASSERT (equal_sign < line + line_len); key_len = equal_sign - line; value = equal_sign + strlen (needle); value_len = strlen (value); if (value_len > 2 && value[0] == '"' && value[value_len - 1] == '"') { value_len -= 2; value++; } /* If we find two copies of either key, the *name == NULL check will fail * so we will just keep the first value encountered. */ if (name_key_len == key_len && strncmp (line, name_key, key_len) == 0 && !(*name)) { *name = bson_strndup (value, value_len); TRACE ("Found name: %s", *name); } else if (version_key_len == key_len && strncmp (line, version_key, key_len) == 0 && !(*version)) { *version = bson_strndup (value, value_len); TRACE ("Found version: %s", *version); } EXIT; } /* * Parse a file of the form: * KEY=VALUE * Looking for name_key and version_key, and storing * their values into *name and *version. * The values in *name and *version must be freed with bson_free. */ void _mongoc_linux_distro_scanner_read_key_value_file (const char *path, const char *name_key, ssize_t name_key_len, char **name, const char *version_key, ssize_t version_key_len, char **version) { const int max_lines = 100; int lines_read = 0; char buffer[LINE_BUFFER_SIZE]; size_t buflen; FILE *f; ENTRY; *name = NULL; *version = NULL; if (name_key_len < 0) { name_key_len = strlen (name_key); } if (version_key_len < 0) { version_key_len = strlen (version_key); } if (access (path, R_OK)) { TRACE ("No permission to read from %s: errno: %d", path, errno); EXIT; } f = fopen (path, "r"); if (!f) { TRACE ("fopen failed on %s: %d", path, errno); EXIT; } while (lines_read < max_lines) { buflen = _fgets_wrapper (buffer, sizeof (buffer), f); if (buflen == 0) { /* Error or eof */ break; } _process_line (name_key, name_key_len, name, version_key, version_key_len, version, buffer, buflen); if (*version && *name) { /* No point in reading any more */ break; } lines_read++; } fclose (f); EXIT; } /* * Find the first string in a list which is a valid file. Assumes * passed in list is NULL terminated! */ const char * _get_first_existing (const char **paths) { const char **p = &paths[0]; ENTRY; for (; *p != NULL; p++) { if (access (*p, F_OK)) { /* Just doesn't exist */ continue; } if (access (*p, R_OK)) { TRACE ("file %s exists, but cannot be read: error %d", *p, errno); continue; } RETURN (*p); } RETURN (NULL); } /* * Given a line of text, split it by the word "release." For example: * Ubuntu release 14.04 => * *name = Ubuntu * *version = 14.04 * If the word "release" isn't found then we put the whole string into *name * (even if the string is empty). */ void _mongoc_linux_distro_scanner_split_line_by_release (const char *line, ssize_t line_len, char **name, char **version) { const char *needle_loc; const char *const needle = " release "; const char *version_string; *name = NULL; *version = NULL; if (line_len < 0) { line_len = strlen (line); } needle_loc = strstr (line, needle); if (!needle_loc) { *name = bson_strdup (line); return; } else if (needle_loc == line) { /* The file starts with the word " release " * This file is weird enough we will just abandon it. */ return; } *name = bson_strndup (line, needle_loc - line); version_string = needle_loc + strlen (needle); if (version_string == line + line_len) { /* Weird. The file just ended with "release " */ return; } *version = bson_strdup (version_string); } /* * Search for a *-release file, and read its contents. */ void _mongoc_linux_distro_scanner_read_generic_release_file (const char **paths, char **name, char **version) { const char *path; size_t buflen; char buffer[LINE_BUFFER_SIZE]; FILE *f; ENTRY; *name = NULL; *version = NULL; path = _get_first_existing (paths); if (!path) { EXIT; } f = fopen (path, "r"); if (!f) { TRACE ("Found %s exists and readable but couldn't open: %d", path, errno); EXIT; } /* Read the first line of the file, look for the word "release" */ buflen = _fgets_wrapper (buffer, sizeof (buffer), f); if (buflen > 0) { TRACE ("Trying to split buffer with contents %s", buffer); /* Try splitting the string. If we can't it'll store everything in * *name. */ _mongoc_linux_distro_scanner_split_line_by_release ( buffer, buflen, name, version); } fclose (f); EXIT; } static void _get_kernel_version_from_uname (char **version) { struct utsname system_info; if (uname (&system_info) >= 0) { *version = bson_strdup_printf ("kernel %s", system_info.release); } else { *version = NULL; } } /* * Some boilerplate logic that tries to set *name and *version to new_name * and new_version if it's not already set. Values of new_name and new_version * should not be used after this call. */ static bool _set_name_and_version_if_needed (char **name, char **version, char *new_name, char *new_version) { if (new_name && !(*name)) { *name = new_name; } else { bson_free (new_name); } if (new_version && !(*version)) { *version = new_version; } else { bson_free (new_version); } return (*name) && (*version); } bool _mongoc_linux_distro_scanner_get_distro (char **name, char **version) { /* In case we decide to try looking up name/version again */ char *new_name; char *new_version; const char *generic_release_paths[] = { "/etc/redhat-release", "/etc/novell-release", "/etc/gentoo-release", "/etc/SuSE-release", "/etc/SUSE-release", "/etc/sles-release", "/etc/debian_release", "/etc/slackware-version", "/etc/centos-release", NULL, }; ENTRY; *name = NULL; *version = NULL; _mongoc_linux_distro_scanner_read_key_value_file ( "/etc/os-release", "NAME", -1, name, "VERSION_ID", -1, version); if (*name && *version) { RETURN (true); } _mongoc_linux_distro_scanner_read_key_value_file ("/etc/lsb-release", "DISTRIB_ID", -1, &new_name, "DISTRIB_RELEASE", -1, &new_version); if (_set_name_and_version_if_needed (name, version, new_name, new_version)) { RETURN (true); } /* Try to read from a generic release file */ _mongoc_linux_distro_scanner_read_generic_release_file ( generic_release_paths, &new_name, &new_version); if (_set_name_and_version_if_needed (name, version, new_name, new_version)) { RETURN (true); } if (*version == NULL) { _get_kernel_version_from_uname (version); } if (*name && *version) { RETURN (true); } bson_free (*name); bson_free (*version); *name = NULL; *version = NULL; RETURN (false); } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-list-private.h0000664000175000017500000000250613210321137023665 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_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.3.4/src/libmongoc/src/mongoc/mongoc-list.c0000664000175000017500000000603713210321137022213 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.3.4/src/libmongoc/src/mongoc/mongoc-log-private.h0000664000175000017500000000226413210321137023474 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) #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); #endif /* MONGOC_LOG_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-log.c0000664000175000017500000001571013210321137022017 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_once_t once = MONGOC_ONCE_INIT; 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) { 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; 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.3.4/src/libmongoc/src/mongoc/mongoc-log.h0000664000175000017500000000777513210321137022040 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 #include "mongoc-macros.h" 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. */ MONGOC_EXPORT (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. * */ MONGOC_EXPORT (void) mongoc_log (mongoc_log_level_t log_level, const char *log_domain, const char *format, ...) BSON_GNUC_PRINTF (3, 4); MONGOC_EXPORT (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 */ MONGOC_EXPORT (const char *) mongoc_log_level_str (mongoc_log_level_t log_level); /** * mongoc_log_trace_enable: * * Enables tracing at runtime (if it has been enabled at compile time). */ MONGOC_EXPORT (void) mongoc_log_trace_enable (void); /** * mongoc_log_trace_disable: * * Disables tracing at runtime (if it has been enabled at compile time). */ MONGOC_EXPORT (void) mongoc_log_trace_disable (void); BSON_END_DECLS #endif /* MONGOC_LOG_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-macros.h0000664000175000017500000000352713210321137022532 0ustar jmikolajmikola/* * Copyright 2017 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_MACROS_H #define MONGOC_MACROS_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif /* Decorate public functions: * - if MONGOC_STATIC, we're compiling a program that uses libmongoc as * a static library, don't decorate functions * - else if MONGOC_COMPILATION, we're compiling a static or shared libmongoc, * mark public functions for export from the shared lib (which has no effect * on the static lib) * - else, we're compiling a program that uses libmongoc as a shared library, * mark public functions as DLL imports for Microsoft Visual C. */ #ifdef _MSC_VER /* * Microsoft Visual C */ #ifdef MONGOC_STATIC #define MONGOC_API #elif defined(MONGOC_COMPILATION) #define MONGOC_API __declspec(dllexport) #else #define MONGOC_API __declspec(dllimport) #endif #define MONGOC_CALL __cdecl #elif defined(__GNUC__) /* * GCC */ #ifdef MONGOC_STATIC #define MONGOC_API #elif defined(MONGOC_COMPILATION) #define MONGOC_API __attribute__ ((visibility ("default"))) #else #define MONGOC_API #endif #define MONGOC_CALL #else /* * Other compilers */ #define MONGOC_API #define MONGOC_CALL #endif #define MONGOC_EXPORT(type) MONGOC_API type MONGOC_CALL #endif /* MONGOC_MACROS_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h0000664000175000017500000000700613210321137024751 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_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.3.4/src/libmongoc/src/mongoc/mongoc-matcher-op.c0000664000175000017500000010232713210321137023276 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.3.4/src/libmongoc/src/mongoc/mongoc-matcher-private.h0000664000175000017500000000171213210321137024333 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_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.3.4/src/libmongoc/src/mongoc/mongoc-matcher.c0000664000175000017500000002650213210321137022662 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.3.4/src/libmongoc/src/mongoc/mongoc-matcher.h0000664000175000017500000000243713210321137022670 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 #include "mongoc-macros.h" BSON_BEGIN_DECLS typedef struct _mongoc_matcher_t mongoc_matcher_t; MONGOC_EXPORT (mongoc_matcher_t *) mongoc_matcher_new (const bson_t *query, bson_error_t *error) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (bool) mongoc_matcher_match (const mongoc_matcher_t *matcher, const bson_t *document) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (void) mongoc_matcher_destroy (mongoc_matcher_t *matcher) BSON_GNUC_DEPRECATED; BSON_END_DECLS #endif /* MONGOC_MATCHER_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-memcmp-private.h0000664000175000017500000000217513210321137024172 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_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.3.4/src/libmongoc/src/mongoc/mongoc-memcmp.c0000664000175000017500000000354213210321137022514 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.3.4/src/libmongoc/src/mongoc/mongoc-opcode.h0000664000175000017500000000223113210321137022506 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_COMPRESSED = 2012, } mongoc_opcode_t; BSON_END_DECLS #endif /* MONGOC_OPCODE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-openssl-private.h0000664000175000017500000000244313210321137024375 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_OPENSSL_PRIVATE_H #define MONGOC_OPENSSL_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include #include #include #include "mongoc-ssl.h" BSON_BEGIN_DECLS bool _mongoc_openssl_check_cert (SSL *ssl, const char *host, bool allow_invalid_hostname); SSL_CTX * _mongoc_openssl_ctx_new (mongoc_ssl_opt_t *opt); char * _mongoc_openssl_extract_subject (const char *filename, const char *passphrase); void _mongoc_openssl_init (void); void _mongoc_openssl_cleanup (void); BSON_END_DECLS #endif /* MONGOC_OPENSSL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-openssl.c0000664000175000017500000004335013210321137022722 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_OPENSSL #include #include #include #include #include #include #include #include #include "mongoc-init.h" #include "mongoc-socket.h" #include "mongoc-ssl.h" #include "mongoc-openssl-private.h" #include "mongoc-trace-private.h" #include "mongoc-thread-private.h" #include "mongoc-util-private.h" #ifdef _WIN32 #include #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L static mongoc_mutex_t *gMongocOpenSslThreadLocks; static void _mongoc_openssl_thread_startup (void); static void _mongoc_openssl_thread_cleanup (void); #endif #ifndef MONGOC_HAVE_ASN1_STRING_GET0_DATA #define ASN1_STRING_get0_data ASN1_STRING_data #endif /** * _mongoc_openssl_init: * * initialization function for SSL * * This needs to get called early on and is not threadsafe. Called by * mongoc_init. */ void _mongoc_openssl_init (void) { SSL_CTX *ctx; SSL_library_init (); SSL_load_error_strings (); ERR_load_BIO_strings (); OpenSSL_add_all_algorithms (); #if OPENSSL_VERSION_NUMBER < 0x10100000L _mongoc_openssl_thread_startup (); #endif ctx = SSL_CTX_new (SSLv23_method ()); if (!ctx) { MONGOC_ERROR ("Failed to initialize OpenSSL."); } SSL_CTX_free (ctx); } void _mongoc_openssl_cleanup (void) { #if OPENSSL_VERSION_NUMBER < 0x10100000L _mongoc_openssl_thread_cleanup (); #endif } static int _mongoc_openssl_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; } #ifdef _WIN32 bool _mongoc_openssl_import_cert_store (LPWSTR store_name, DWORD dwFlags, X509_STORE *openssl_store) { PCCERT_CONTEXT cert = NULL; HCERTSTORE cert_store; cert_store = CertOpenStore ( CERT_STORE_PROV_SYSTEM, /* provider */ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */ 0, /* unused */ dwFlags, /* dwFlags */ store_name); /* system store name. "My" or "Root" */ if (cert_store == NULL) { LPTSTR msg = NULL; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError (), LANG_NEUTRAL, (LPTSTR) &msg, 0, NULL); MONGOC_ERROR ("Can't open CA store: 0x%.8X: '%s'", GetLastError (), msg); LocalFree (msg); return false; } while ((cert = CertEnumCertificatesInStore (cert_store, cert)) != NULL) { X509 *x509Obj = d2i_X509 (NULL, (const unsigned char **) &cert->pbCertEncoded, cert->cbCertEncoded); if (x509Obj == NULL) { MONGOC_WARNING ( "Error parsing X509 object from Windows certificate store"); continue; } X509_STORE_add_cert (openssl_store, x509Obj); X509_free (x509Obj); } CertCloseStore (cert_store, 0); return true; } bool _mongoc_openssl_import_cert_stores (SSL_CTX *context) { bool retval; X509_STORE *store = SSL_CTX_get_cert_store (context); if (!store) { MONGOC_WARNING ("no X509 store found for SSL context while loading " "system certificates"); return false; } retval = _mongoc_openssl_import_cert_store (L"root", CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, store); retval &= _mongoc_openssl_import_cert_store ( L"CA", CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, store); return retval; } #endif /** mongoc_openssl_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_openssl_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; TRACE ("Comparing '%s' == '%s'", pattern, hostname); 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_openssl_check_cert (SSL *ssl, const char *host, bool allow_invalid_hostname) { X509 *peer; X509_NAME *subject_name; X509_NAME_ENTRY *entry; ASN1_STRING *entry_data; int length; int idx; int r = 0; long verify_status; size_t addrlen = 0; unsigned char addr4[sizeof (struct in_addr)]; unsigned char addr6[sizeof (struct in6_addr)]; int i; int n_sans = -1; int target = GEN_DNS; STACK_OF (GENERAL_NAME) *sans = NULL; ENTRY; BSON_ASSERT (ssl); BSON_ASSERT (host); if (allow_invalid_hostname) { 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, &addr4)) { target = GEN_IPADD; addrlen = sizeof addr4; } else if (inet_pton (AF_INET6, host, &addr6)) { target = GEN_IPADD; addrlen = sizeof addr6; } peer = SSL_get_peer_certificate (ssl); if (!peer) { MONGOC_WARNING ("SSL Certification verification failed: %s", ERR_error_string (ERR_get_error (), NULL)); RETURN (false); } verify_status = SSL_get_verify_result (ssl); if (verify_status == X509_V_OK) { /* gets 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) { const char *check; check = (const char *) ASN1_STRING_get0_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_openssl_hostcheck (check, host)) { r = 1; } break; case GEN_IPADD: if (length == addrlen) { if (length == sizeof addr6 && !memcmp (check, &addr6, length)) { r = 1; } else if (length == sizeof addr4 && !memcmp (check, &addr4, length)) { r = 1; } } break; default: BSON_ASSERT (0); break; } } } GENERAL_NAMES_free (sans); } else { subject_name = X509_get_subject_name (peer); if (subject_name) { 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) { char *check; /* 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_openssl_hostcheck (check, host)) { r = 1; } OPENSSL_free (check); } } } } } } X509_free (peer); RETURN (r); } static bool _mongoc_openssl_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)) { MONGOC_ERROR ("Cannot load Certificate Authorities from '%s' and '%s'", cert, cert_dir); return 0; } return 1; } static bool _mongoc_openssl_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_openssl_setup_pem_file (SSL_CTX *ctx, const char *pem_file, const char *password) { if (!SSL_CTX_use_certificate_chain_file (ctx, pem_file)) { MONGOC_ERROR ("Cannot find certificate in '%s'", pem_file); return 0; } if (password) { SSL_CTX_set_default_passwd_cb_userdata (ctx, (void *) password); SSL_CTX_set_default_passwd_cb (ctx, _mongoc_openssl_password_cb); } if (!(SSL_CTX_use_PrivateKey_file (ctx, pem_file, SSL_FILETYPE_PEM))) { MONGOC_ERROR ("Cannot find private key in: '%s'", pem_file); return 0; } if (!(SSL_CTX_check_private_key (ctx))) { MONGOC_ERROR ("Cannot load private key: '%s'", pem_file); return 0; } return 1; } /** * _mongoc_openssl_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_openssl_ctx_new (mongoc_ssl_opt_t *opt) { SSL_CTX *ctx = NULL; int ssl_ctx_options = 0; /* * 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_ctx_options |= SSL_OP_ALL; /* SSL_OP_NO_SSLv2 - Disable SSL v2 support */ ssl_ctx_options |= SSL_OP_NO_SSLv2; /* Disable compression, if we can. * OpenSSL 0.9.x added compression support which was always enabled when built * against zlib * OpenSSL 1.0.0 added the ability to disable it, while keeping it enabled by * default * OpenSSL 1.1.0 disabled it by default. */ #if OPENSSL_VERSION_NUMBER >= 0x10000000L ssl_ctx_options |= SSL_OP_NO_COMPRESSION; #endif SSL_CTX_set_options (ctx, ssl_ctx_options); /* only defined in special build, using: * --enable-system-crypto-profile (autotools) * -DENABLE_CRYPTO_SYSTEM_PROFILE:BOOL=ON (cmake) */ #ifndef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE /* 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"); #endif /* 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); /* Load my private keys to present to the server */ if (opt->pem_file && !_mongoc_openssl_setup_pem_file (ctx, opt->pem_file, opt->pem_pwd)) { SSL_CTX_free (ctx); return NULL; } /* Load in my Certificate Authority, to verify the server against * If none provided, fallback to the distro defaults */ if (opt->ca_file || opt->ca_dir) { if (!_mongoc_openssl_setup_ca (ctx, opt->ca_file, opt->ca_dir)) { SSL_CTX_free (ctx); return NULL; } } else { /* If the server certificate is issued by known CA we trust it by default */ #ifdef _WIN32 _mongoc_openssl_import_cert_stores (ctx); #else SSL_CTX_set_default_verify_paths (ctx); #endif } /* Load my revocation list, to verify the server against */ if (opt->crl_file && !_mongoc_openssl_setup_crl (ctx, opt->crl_file)) { SSL_CTX_free (ctx); return NULL; } return ctx; } char * _mongoc_openssl_extract_subject (const char *filename, const char *passphrase) { 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); if (BIO_read_filename (certbio, filename) && (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; } #if OPENSSL_VERSION_NUMBER < 0x10100000L #ifdef _WIN32 static unsigned long _mongoc_openssl_thread_id_callback (void) { unsigned long ret; ret = (unsigned long) GetCurrentThreadId (); return ret; } #else static unsigned long _mongoc_openssl_thread_id_callback (void) { unsigned long ret; ret = (unsigned long) pthread_self (); return ret; } #endif static void _mongoc_openssl_thread_locking_callback (int mode, int type, const char *file, int line) { if (mode & CRYPTO_LOCK) { mongoc_mutex_lock (&gMongocOpenSslThreadLocks[type]); } else { mongoc_mutex_unlock (&gMongocOpenSslThreadLocks[type]); } } static void _mongoc_openssl_thread_startup (void) { int i; gMongocOpenSslThreadLocks = (mongoc_mutex_t *) OPENSSL_malloc ( CRYPTO_num_locks () * sizeof (mongoc_mutex_t)); for (i = 0; i < CRYPTO_num_locks (); i++) { mongoc_mutex_init (&gMongocOpenSslThreadLocks[i]); } if (!CRYPTO_get_locking_callback ()) { CRYPTO_set_locking_callback (_mongoc_openssl_thread_locking_callback); CRYPTO_set_id_callback (_mongoc_openssl_thread_id_callback); } } static void _mongoc_openssl_thread_cleanup (void) { int i; if (CRYPTO_get_locking_callback () == _mongoc_openssl_thread_locking_callback) { CRYPTO_set_locking_callback (NULL); CRYPTO_set_id_callback (NULL); } for (i = 0; i < CRYPTO_num_locks (); i++) { mongoc_mutex_destroy (&gMongocOpenSslThreadLocks[i]); } OPENSSL_free (gMongocOpenSslThreadLocks); } #endif #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-queue-private.h0000664000175000017500000000315313210321137024035 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_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; uint32_t length; }; 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_pop_tail (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.3.4/src/libmongoc/src/mongoc/mongoc-queue.c0000664000175000017500000000512013210321137022354 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; } queue->length++; } 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; queue->length++; } 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); queue->length--; } return data; } void * _mongoc_queue_pop_tail (mongoc_queue_t *queue) { mongoc_queue_item_t *item; void *data = NULL; BSON_ASSERT (queue); if (queue->length == 0) { return NULL; } data = queue->tail->data; if (queue->length == 1) { bson_free (queue->tail); queue->head = queue->tail = NULL; } else { /* find item pointing at tail */ for (item = queue->head; item; item = item->next) { if (item->next == queue->tail) { item->next = NULL; bson_free (queue->tail); queue->tail = item; break; } } } queue->length--; return data; } uint32_t _mongoc_queue_get_length (const mongoc_queue_t *queue) { BSON_ASSERT (queue); return queue->length; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-rand-cng.c0000664000175000017500000000330113210321137022720 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_CHANNEL #include "mongoc-rand.h" #include "mongoc-rand-private.h" #include "mongoc.h" #include #include #include #define NT_SUCCESS(Status) (((NTSTATUS) (Status)) >= 0) #define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) int _mongoc_rand_bytes (uint8_t *buf, int num) { static BCRYPT_ALG_HANDLE algorithm = 0; NTSTATUS status = 0; if (!algorithm) { status = BCryptOpenAlgorithmProvider ( &algorithm, BCRYPT_RNG_ALGORITHM, NULL, 0); if (!NT_SUCCESS (status)) { MONGOC_ERROR ("BCryptOpenAlgorithmProvider(): %d", status); return 0; } } status = BCryptGenRandom (algorithm, buf, num, 0); if (NT_SUCCESS (status)) { return 1; } MONGOC_ERROR ("BCryptGenRandom(): %d", status); return 0; } void mongoc_rand_seed (const void *buf, int num) { /* N/A - OS Does not need entropy seed */ } void mongoc_rand_add (const void *buf, int num, double entropy) { /* N/A - OS Does not need entropy seed */ } int mongoc_rand_status (void) { return 1; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-rand-common-crypto.c0000664000175000017500000000233513210321137024765 0ustar jmikolajmikola/* * Copyright 2016 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_CRYPTO_COMMON_CRYPTO #include "mongoc-rand.h" #include "mongoc-rand-private.h" #include "mongoc.h" #include /* rumour has it this wasn't in standard Security.h in ~10.8 */ #include int _mongoc_rand_bytes (uint8_t *buf, int num) { return !SecRandomCopyBytes (kSecRandomDefault, num, buf); } void mongoc_rand_seed (const void *buf, int num) { /* No such thing in Common Crypto */ } void mongoc_rand_add (const void *buf, int num, double entropy) { /* No such thing in Common Crypto */ } int mongoc_rand_status (void) { return 1; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-rand-openssl.c0000664000175000017500000000212013210321137023632 0ustar jmikolajmikola/* * Copyright 2016 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_CRYPTO_LIBCRYPTO #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); } 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.3.4/src/libmongoc/src/mongoc/mongoc-rand-private.h0000664000175000017500000000157313210321137023641 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_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); BSON_END_DECLS #endif /* MONGOC_RAND_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-rand.h0000664000175000017500000000205313210321137022163 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 #include "mongoc-macros.h" BSON_BEGIN_DECLS MONGOC_EXPORT (void) mongoc_rand_seed (const void *buf, int num); MONGOC_EXPORT (void) mongoc_rand_add (const void *buf, int num, double entropy); MONGOC_EXPORT (int) mongoc_rand_status (void); BSON_END_DECLS #endif /* MONGOC_RAND_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-read-concern-private.h0000664000175000017500000000205713210321137025253 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_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.3.4/src/libmongoc/src/mongoc/mongoc-read-concern.c0000664000175000017500000001232613210321137023576 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 compatibility * but MongoDB 3.2 only accepts "local" and "majority", aka: * - MONGOC_READ_CONCERN_LEVEL_LOCAL * - MONGOC_READ_CONCERN_LEVEL_MAJORITY * MongoDB 3.4 added * - MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE * * 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_append: * @read_concern: (in): A mongoc_read_concern_t. * @opts: (out): A pointer to a bson document. * * Appends a read_concern document to command options to send to * a server. * * Returns true on success, false on failure. * */ bool mongoc_read_concern_append (mongoc_read_concern_t *read_concern, bson_t *command) { BSON_ASSERT (read_concern); if (!read_concern->level) { return true; } if (!bson_append_document (command, "readConcern", 11, _mongoc_read_concern_get_bson (read_concern))) { MONGOC_ERROR ("Could not append readConcern to command."); return false; } return true; } /** * mongoc_read_concern_is_default: * @read_concern: A const mongoc_read_concern_t. * * Returns true when read_concern has not been modified. */ bool mongoc_read_concern_is_default (const mongoc_read_concern_t *read_concern) { return !read_concern || !read_concern->level; } /** * 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.3.4/src/libmongoc/src/mongoc/mongoc-read-concern.h0000664000175000017500000000345213210321137023603 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 #include "mongoc-macros.h" BSON_BEGIN_DECLS #define MONGOC_READ_CONCERN_LEVEL_LOCAL "local" #define MONGOC_READ_CONCERN_LEVEL_MAJORITY "majority" #define MONGOC_READ_CONCERN_LEVEL_LINEARIZABLE "linearizable" typedef struct _mongoc_read_concern_t mongoc_read_concern_t; MONGOC_EXPORT (mongoc_read_concern_t *) mongoc_read_concern_new (void); MONGOC_EXPORT (mongoc_read_concern_t *) mongoc_read_concern_copy (const mongoc_read_concern_t *read_concern); MONGOC_EXPORT (void) mongoc_read_concern_destroy (mongoc_read_concern_t *read_concern); MONGOC_EXPORT (const char *) mongoc_read_concern_get_level (const mongoc_read_concern_t *read_concern); MONGOC_EXPORT (bool) mongoc_read_concern_set_level (mongoc_read_concern_t *read_concern, const char *level); MONGOC_EXPORT (bool) mongoc_read_concern_append (mongoc_read_concern_t *read_concern, bson_t *doc); MONGOC_EXPORT (bool) mongoc_read_concern_is_default (const mongoc_read_concern_t *read_concern); BSON_END_DECLS #endif /* MONGOC_READ_CONCERN_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h0000664000175000017500000000360413210321137024742 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_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; int64_t max_staleness_seconds; }; 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 \ } const char * _mongoc_read_mode_as_str (mongoc_read_mode_t mode); 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); bool _mongoc_read_prefs_validate (const mongoc_read_prefs_t *read_prefs, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_READ_PREFS_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-read-prefs.c0000664000175000017500000002432713210321137023272 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" #include "mongoc-error.h" #include "mongoc-read-prefs-private.h" #include "mongoc-trace-private.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); read_prefs->max_staleness_seconds = MONGOC_NO_MAX_STALENESS; 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); } } int64_t mongoc_read_prefs_get_max_staleness_seconds ( const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (read_prefs); return read_prefs->max_staleness_seconds; } void mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs, int64_t max_staleness_seconds) { BSON_ASSERT (read_prefs); read_prefs->max_staleness_seconds = max_staleness_seconds; } bool mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (read_prefs); /* * Tags or maxStalenessSeconds are not supported with PRIMARY mode. */ if (read_prefs->mode == MONGOC_READ_PRIMARY) { if (!bson_empty (&read_prefs->tags) || read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { return false; } } if (read_prefs->max_staleness_seconds != MONGOC_NO_MAX_STALENESS && read_prefs->max_staleness_seconds <= 0) { 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); ret->max_staleness_seconds = read_prefs->max_staleness_seconds; } return ret; } const char * _mongoc_read_mode_as_str (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; int64_t max_staleness_seconds; 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 = _mongoc_read_mode_as_str (mode); bson_append_utf8 (&child, "mode", 4, mode_str, -1); if (!bson_empty0 (tags)) { bson_append_array (&child, "tags", 4, tags); } max_staleness_seconds = mongoc_read_prefs_get_max_staleness_seconds (read_prefs); if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { bson_append_int64 ( &child, "maxStalenessSeconds", 19, max_staleness_seconds); } 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. * * Note: * This function, the mongoc_apply_read_prefs_result_t struct, and all * related functions are only used for find operations with OP_QUERY. * Remove them once MongoDB 3.0 is EOL, all find operations will then * use the "find" command. * *-------------------------------------------------------------------------- */ 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; } bool _mongoc_read_prefs_validate (const mongoc_read_prefs_t *read_prefs, bson_error_t *error) { if (read_prefs && !mongoc_read_prefs_is_valid (read_prefs)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Invalid mongoc_read_prefs_t"); return false; } return true; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-read-prefs.h0000664000175000017500000000504113210321137023267 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 #include "mongoc-macros.h" #include "mongoc-config.h" BSON_BEGIN_DECLS #define MONGOC_NO_MAX_STALENESS -1 #define MONGOC_SMALLEST_MAX_STALENESS_SECONDS 90 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_EXPORT (mongoc_read_prefs_t *) mongoc_read_prefs_new (mongoc_read_mode_t read_mode); MONGOC_EXPORT (mongoc_read_prefs_t *) mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs); MONGOC_EXPORT (void) mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs); MONGOC_EXPORT (mongoc_read_mode_t) mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs); MONGOC_EXPORT (void) mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs, mongoc_read_mode_t mode); MONGOC_EXPORT (const bson_t *) mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs); MONGOC_EXPORT (void) mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs, const bson_t *tags); MONGOC_EXPORT (void) mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag); MONGOC_EXPORT (int64_t) mongoc_read_prefs_get_max_staleness_seconds ( const mongoc_read_prefs_t *read_prefs); MONGOC_EXPORT (void) mongoc_read_prefs_set_max_staleness_seconds (mongoc_read_prefs_t *read_prefs, int64_t max_staleness_seconds); MONGOC_EXPORT (bool) mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs); BSON_END_DECLS #endif /* MONGOC_READ_PREFS_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-rpc-private.h0000664000175000017500000001111413210321137023471 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_COMPILATION) #error "Only can be included directly." #endif #include #include #include "mongoc-array-private.h" #include "mongoc-cmd-private.h" #include "mongoc-iovec.h" #include "mongoc-write-concern.h" #include "mongoc-flags.h" /* forward declaration */ struct _mongoc_cluster_t; 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 UINT8_FIELD(_name) uint8_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 #pragma pack(1) #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-reply-header.def" #include "op-update.def" #include "op-compressed.def" /* restore default packing */ #pragma pack() 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_reply_header_t reply_header; mongoc_rpc_update_t update; mongoc_rpc_compressed_t compressed; } 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)); BSON_STATIC_ASSERT (sizeof (mongoc_rpc_reply_header_t) == 36); #undef RPC #undef ENUM_FIELD #undef UINT8_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_scatter_reply_header_only (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen); bool _mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply); 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, mongoc_cmd_t *cmd); bool _mongoc_rpc_check_ok (mongoc_rpc_t *rpc, bool is_command, int32_t error_api_version, bson_error_t *error /* OUT */, bson_t *error_doc /* OUT */); bool _mongoc_cmd_check_ok (const bson_t *doc, int32_t error_api_version, bson_error_t *error); bool _mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen); char * _mongoc_rpc_compress (struct _mongoc_cluster_t *cluster, int32_t compressor_id, mongoc_rpc_t *rpc_le, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_RPC_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-rpc.c0000664000175000017500000011336013210321137022022 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-private.h" #include "mongoc-util-private.h" #include "mongoc-compression-private.h" #include "mongoc-cluster-private.h" #define RPC(_name, _code) \ static void _mongoc_rpc_gather_##_name (mongoc_rpc_##_name##_t *rpc, \ mongoc_rpc_header_t *header, \ mongoc_array_t *array) \ { \ mongoc_iovec_t iov; \ BSON_ASSERT (rpc); \ BSON_ASSERT (array); \ header->msg_len = 0; \ _code \ } #define UINT8_FIELD(_name) \ iov.iov_base = (void *) &rpc->_name; \ iov.iov_len = 1; \ header->msg_len += (int32_t) iov.iov_len; \ _mongoc_array_append_val (array, iov); #define INT32_FIELD(_name) \ iov.iov_base = (void *) &rpc->_name; \ iov.iov_len = 4; \ header->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; \ header->msg_len += (int32_t) iov.iov_len; \ _mongoc_array_append_val (array, iov); #define CSTRING_FIELD(_name) \ BSON_ASSERT (rpc->_name); \ iov.iov_base = (void *) rpc->_name; \ iov.iov_len = strlen (rpc->_name) + 1; \ header->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; \ header->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; \ header->msg_len += (int32_t) iov.iov_len; \ _mongoc_array_append_val (array, iov); \ } #define IOVEC_ARRAY_FIELD(_name) \ do { \ ssize_t _i; \ BSON_ASSERT (rpc->n_##_name); \ for (_i = 0; _i < rpc->n_##_name; _i++) { \ BSON_ASSERT (rpc->_name[_i].iov_len); \ header->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; \ BSON_ASSERT (iov.iov_len); \ header->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; \ header->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; \ BSON_ASSERT (iov.iov_len); \ header->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-compressed.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef UINT8_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) \ { \ BSON_ASSERT (rpc); \ _code \ } #define UINT8_FIELD(_name) #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-compressed.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) \ { \ BSON_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-compressed.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef UINT8_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) \ { \ BSON_ASSERT (rpc); \ _code \ } #define UINT8_FIELD(_name) printf (" " #_name " : %u\n", rpc->_name); #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_canonical_extended_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_canonical_extended_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-compressed.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef UINT8_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) \ { \ BSON_ASSERT (rpc); \ BSON_ASSERT (buf); \ BSON_ASSERT (buflen); \ _code return true; \ } #define UINT8_FIELD(_name) \ if (buflen < 1) { \ return false; \ } \ memcpy (&rpc->_name, buf, 1); \ buflen -= 1; \ buf += 1; #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-reply-header.def" #include "op-compressed.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef UINT8_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 /* *-------------------------------------------------------------------------- * * _mongoc_rpc_gather -- * * Takes a (native endian) rpc struct and gathers the buffer. * Caller should swab to little endian after calling gather. * * Gather, swab, compress write. * Read, scatter, uncompress, swab * *-------------------------------------------------------------------------- */ 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, &rpc->header, array); return; case MONGOC_OPCODE_MSG: _mongoc_rpc_gather_msg (&rpc->msg, &rpc->header, array); return; case MONGOC_OPCODE_UPDATE: _mongoc_rpc_gather_update (&rpc->update, &rpc->header, array); return; case MONGOC_OPCODE_INSERT: _mongoc_rpc_gather_insert (&rpc->insert, &rpc->header, array); return; case MONGOC_OPCODE_QUERY: _mongoc_rpc_gather_query (&rpc->query, &rpc->header, array); return; case MONGOC_OPCODE_GET_MORE: _mongoc_rpc_gather_get_more (&rpc->get_more, &rpc->header, array); return; case MONGOC_OPCODE_DELETE: _mongoc_rpc_gather_delete (&rpc->delete_, &rpc->header, array); return; case MONGOC_OPCODE_KILL_CURSORS: _mongoc_rpc_gather_kill_cursors (&rpc->kill_cursors, &rpc->header, array); return; case MONGOC_OPCODE_COMPRESSED: _mongoc_rpc_gather_compressed (&rpc->compressed, &rpc->header, 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; case MONGOC_OPCODE_COMPRESSED: _mongoc_rpc_swab_to_le_compressed (&rpc->compressed); break; default: MONGOC_WARNING ("Unknown rpc type: 0x%08x", opcode); break; } #endif #if 0 _mongoc_rpc_printf (&rpc); #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; case MONGOC_OPCODE_COMPRESSED: _mongoc_rpc_swab_from_le_compressed (&rpc->compressed); break; default: MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); break; } #endif #if 0 _mongoc_rpc_printf (&rpc); #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; case MONGOC_OPCODE_COMPRESSED: _mongoc_rpc_printf_compressed (&rpc->compressed); break; default: MONGOC_WARNING ("Unknown rpc type: 0x%08x", rpc->header.opcode); break; } } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_decompress -- * * Takes a (little endian) rpc struct assumed to be OP_COMPRESSED * and decompresses the opcode into its original opcode. * The in-place updated rpc struct remains little endian. * * Side effects: * Overwrites the RPC, along with the provided buf with the * compressed results. * *-------------------------------------------------------------------------- */ bool _mongoc_rpc_decompress (mongoc_rpc_t *rpc_le, uint8_t *buf, size_t buflen) { size_t uncompressed_size = BSON_UINT32_FROM_LE (rpc_le->compressed.uncompressed_size); bool ok; size_t msg_len = BSON_UINT32_TO_LE (buflen); BSON_ASSERT (uncompressed_size <= buflen); memcpy (buf, (void *) (&msg_len), 4); memcpy (buf + 4, (void *) (&rpc_le->header.request_id), 4); memcpy (buf + 8, (void *) (&rpc_le->header.response_to), 4); memcpy (buf + 12, (void *) (&rpc_le->compressed.original_opcode), 4); ok = mongoc_uncompress (rpc_le->compressed.compressor_id, rpc_le->compressed.compressed_message, rpc_le->compressed.compressed_message_len, buf + 16, &uncompressed_size); if (ok) { return _mongoc_rpc_scatter (rpc_le, buf, buflen); } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_compress -- * * Takes a (little endian) rpc struct and creates a OP_COMPRESSED * compressed opcode based on the provided compressor_id. * The in-place updated rpc struct remains little endian. * * Side effects: * Overwrites the RPC, and clears and overwrites the cluster buffer * with the compressed results. * *-------------------------------------------------------------------------- */ char * _mongoc_rpc_compress (struct _mongoc_cluster_t *cluster, int32_t compressor_id, mongoc_rpc_t *rpc_le, bson_error_t *error) { char *output; size_t output_length = 0; size_t allocate = BSON_UINT32_FROM_LE (rpc_le->header.msg_len) - 16; char *data; int size; int32_t compression_level = -1; if (compressor_id == MONGOC_COMPRESSOR_ZLIB_ID) { compression_level = mongoc_uri_get_option_as_int32 ( cluster->uri, MONGOC_URI_ZLIBCOMPRESSIONLEVEL, -1); } BSON_ASSERT (allocate > 0); data = bson_malloc0 (allocate); size = _mongoc_cluster_buffer_iovec ( cluster->iov.data, cluster->iov.len, 16, data); BSON_ASSERT (size); output_length = mongoc_compressor_max_compressed_length (compressor_id, size); if (!output_length) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Could not determine compression bounds for %s", mongoc_compressor_id_to_name (compressor_id)); bson_free (data); return NULL; } output = (char *) bson_malloc0 (output_length); if (mongoc_compress (compressor_id, compression_level, data, size, output, &output_length)) { rpc_le->header.msg_len = 0; rpc_le->compressed.original_opcode = BSON_UINT32_FROM_LE (rpc_le->header.opcode); rpc_le->header.opcode = MONGOC_OPCODE_COMPRESSED; rpc_le->header.request_id = BSON_UINT32_FROM_LE (rpc_le->header.request_id); rpc_le->header.response_to = BSON_UINT32_FROM_LE (rpc_le->header.response_to); rpc_le->compressed.uncompressed_size = size; rpc_le->compressed.compressor_id = compressor_id; rpc_le->compressed.compressed_message = (const uint8_t *) output; rpc_le->compressed.compressed_message_len = output_length; bson_free (data); _mongoc_array_destroy (&cluster->iov); _mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t)); _mongoc_rpc_gather (rpc_le, &cluster->iov); _mongoc_rpc_swab_to_le (rpc_le); return output; } else { MONGOC_WARNING ("Could not compress data with %s", mongoc_compressor_id_to_name (compressor_id)); } bson_free (data); bson_free (output); return NULL; } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_scatter -- * * Takes a (little endian) rpc struct and scatters the buffer. * Caller should check if resulting opcode is OP_COMPRESSED * BEFORE swabbing to native endianness. * *-------------------------------------------------------------------------- */ 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_COMPRESSED: return _mongoc_rpc_scatter_compressed (&rpc->compressed, buf, buflen); 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_scatter_reply_header_only (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen) { if (BSON_UNLIKELY (buflen < sizeof (mongoc_rpc_reply_header_t))) { return false; } return _mongoc_rpc_scatter_reply_header (&rpc->reply_header, buf, buflen); } bool _mongoc_rpc_get_first_document (mongoc_rpc_t *rpc, bson_t *reply) { if (rpc->header.opcode == MONGOC_OPCODE_REPLY && _mongoc_rpc_reply_get_first (&rpc->reply, reply)) { return true; } 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: case MONGOC_OPCODE_COMPRESSED: 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 * @cmd 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, mongoc_cmd_t *cmd) { rpc->header.msg_len = 0; rpc->header.request_id = 0; rpc->header.response_to = 0; rpc->header.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 (cmd->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 = cmd->query_flags & MONGOC_QUERY_SLAVE_OK; } /* *-------------------------------------------------------------------------- * * _mongoc_cmd_check_ok -- * * Check if a server reply document is an error message. * Optionally fill out a bson_error_t from the server error. * Does *not* check for writeConcernError. * * Returns: * false if @doc is an error message, true otherwise. * * Side effects: * If @doc is an error reply and @error is not NULL, set its * domain, code, and message. * *-------------------------------------------------------------------------- */ bool _mongoc_cmd_check_ok (const bson_t *doc, int32_t error_api_version, bson_error_t *error) { mongoc_error_domain_t domain = error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER : MONGOC_ERROR_QUERY; uint32_t code = MONGOC_ERROR_QUERY_FAILURE; bson_iter_t iter; const char *msg = "Unknown command error"; ENTRY; BSON_ASSERT (doc); if (bson_iter_init_find (&iter, doc, "ok") && bson_iter_as_bool (&iter)) { /* no error */ RETURN (true); } if (bson_iter_init_find (&iter, doc, "code") && BSON_ITER_HOLDS_INT32 (&iter)) { code = (uint32_t) bson_iter_int32 (&iter); } if (code == MONGOC_ERROR_PROTOCOL_ERROR || code == 13390) { code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND; } if (bson_iter_init_find (&iter, doc, "errmsg") && BSON_ITER_HOLDS_UTF8 (&iter)) { msg = bson_iter_utf8 (&iter, NULL); } else if (bson_iter_init_find (&iter, doc, "$err") && BSON_ITER_HOLDS_UTF8 (&iter)) { msg = bson_iter_utf8 (&iter, NULL); } bson_set_error (error, domain, code, "%s", msg); /* there was a command error */ RETURN (false); } /* helper function to parse error reply document to an OP_QUERY */ static void _mongoc_populate_query_error (const bson_t *doc, int32_t error_api_version, bson_error_t *error) { mongoc_error_domain_t domain = error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER : MONGOC_ERROR_QUERY; uint32_t code = MONGOC_ERROR_QUERY_FAILURE; bson_iter_t iter; const char *msg = "Unknown query failure"; ENTRY; BSON_ASSERT (doc); if (bson_iter_init_find (&iter, doc, "code") && BSON_ITER_HOLDS_INT32 (&iter)) { code = (uint32_t) bson_iter_int32 (&iter); } if (bson_iter_init_find (&iter, doc, "$err") && BSON_ITER_HOLDS_UTF8 (&iter)) { msg = bson_iter_utf8 (&iter, NULL); } bson_set_error (error, domain, code, "%s", msg); EXIT; } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_check_ok -- * * Check if a server OP_REPLY is an error message. * Optionally fill out a bson_error_t from the server error. * @error_document must be an initialized bson_t or NULL. * Does *not* check for writeConcernError. * * Returns: * false if the reply is an error message, true otherwise. * * Side effects: * If rpc is an error reply and @error is not NULL, set its * domain, code, and message. * * If rpc is an error reply and @error_document is not NULL, * it is reinitialized with the server reply. * *-------------------------------------------------------------------------- */ bool _mongoc_rpc_check_ok (mongoc_rpc_t *rpc, bool is_command, int32_t error_api_version, bson_error_t *error /* OUT */, bson_t *error_doc /* OUT */) { bson_t b; bool r; 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 (false); } if (is_command) { if (rpc->reply.n_returned != 1) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Expected only one reply document, got %d", rpc->reply.n_returned); RETURN (false); } if (_mongoc_rpc_get_first_document (rpc, &b)) { r = _mongoc_cmd_check_ok (&b, error_api_version, error); if (!r && error_doc) { bson_destroy (error_doc); bson_copy_to (&b, error_doc); } bson_destroy (&b); RETURN (r); } else { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Failed to decode document from the server."); RETURN (false); } } else if (rpc->reply.flags & MONGOC_REPLY_QUERY_FAILURE) { if (_mongoc_rpc_get_first_document (rpc, &b)) { _mongoc_populate_query_error (&b, error_api_version, error); if (error_doc) { bson_destroy (error_doc); bson_copy_to (&b, error_doc); } bson_destroy (&b); } else { bson_set_error (error, MONGOC_ERROR_QUERY, MONGOC_ERROR_QUERY_FAILURE, "Unknown query failure."); } RETURN (false); } else 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 (false); } RETURN (true); } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-sasl-private.h0000664000175000017500000000366713210321137023665 0ustar jmikolajmikola/* * Copyright 2017 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_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-uri.h" #include "mongoc-stream-private.h" #include "mongoc-stream.h" #include "mongoc-stream-socket.h" BSON_BEGIN_DECLS typedef struct { char *user; char *pass; char *service_name; char *service_host; bool canonicalize_host_name; char *mechanism; } mongoc_sasl_t; void _mongoc_sasl_set_pass (mongoc_sasl_t *sasl, const char *pass); void _mongoc_sasl_set_user (mongoc_sasl_t *sasl, const char *user); bool _mongoc_sasl_set_mechanism (mongoc_sasl_t *sasl, const char *mechanism, bson_error_t *error); 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_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri); bool _mongoc_sasl_get_canonicalized_name (mongoc_stream_t *node_stream, /* IN */ char *name, /* OUT */ size_t namelen, /* IN */ bson_error_t *error); /* OUT */ BSON_END_DECLS #endif /* MONGOC_SASL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-sasl.c0000664000175000017500000001214113210321137022173 0ustar jmikolajmikola/* * Copyright 2017 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 "mongoc-sasl-private.h" #include "mongoc-util-private.h" #include "mongoc-trace-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "SASL" 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_pass (mongoc_sasl_t *sasl, const char *pass) { BSON_ASSERT (sasl); bson_free (sasl->pass); sasl->pass = pass ? bson_strdup (pass) : 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_set_properties (mongoc_sasl_t *sasl, const mongoc_uri_t *uri) { const bson_t *options; bson_iter_t iter; bson_t properties; const char *service_name = NULL; bool canonicalize = false; options = mongoc_uri_get_options (uri); if (!mongoc_uri_get_mechanism_properties (uri, &properties)) { bson_init (&properties); } if (bson_iter_init_find_case ( &iter, options, MONGOC_URI_GSSAPISERVICENAME) && BSON_ITER_HOLDS_UTF8 (&iter)) { service_name = bson_iter_utf8 (&iter, NULL); } if (bson_iter_init_find_case (&iter, &properties, "SERVICE_NAME") && BSON_ITER_HOLDS_UTF8 (&iter)) { /* newer "authMechanismProperties" URI syntax takes precedence */ service_name = bson_iter_utf8 (&iter, NULL); } _mongoc_sasl_set_service_name (sasl, service_name); /* * Driver Authentication Spec: "Drivers MAY allow the user to request * canonicalization of the hostname. This might be required when the hosts * report different hostnames than what is used in the kerberos database. * The default is "false". * * Some underlying GSSAPI layers will do this for us, but can be disabled in * their config (krb.conf). * * See CDRIVER-323 for more information. */ if (bson_iter_init_find_case ( &iter, options, MONGOC_URI_CANONICALIZEHOSTNAME) && BSON_ITER_HOLDS_BOOL (&iter)) { canonicalize = bson_iter_bool (&iter); } if (bson_iter_init_find_case ( &iter, &properties, "CANONICALIZE_HOST_NAME") && BSON_ITER_HOLDS_UTF8 (&iter)) { /* newer "authMechanismProperties" URI syntax takes precedence */ canonicalize = !strcasecmp (bson_iter_utf8 (&iter, NULL), "true"); } sasl->canonicalize_host_name = canonicalize; bson_destroy (&properties); } /* *-------------------------------------------------------------------------- * * _mongoc_sasl_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. * *-------------------------------------------------------------------------- */ bool _mongoc_sasl_get_canonicalized_name (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 (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 mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-scram-private.h0000664000175000017500000000460713210321137024023 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_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_SCRAM_PRIVATE_H #define MONGOC_SCRAM_PRIVATE_H #include #include "mongoc-crypto-private.h" BSON_BEGIN_DECLS #define MONGOC_SCRAM_HASH_SIZE 20 typedef struct _mongoc_scram_t { bool done; int step; char *user; char *pass; uint8_t client_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t server_key[MONGOC_SCRAM_HASH_SIZE]; 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; #ifdef MONGOC_ENABLE_CRYPTO mongoc_crypto_t crypto; #endif } 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_set_client_key (mongoc_scram_t *scram, const uint8_t *client_key, size_t len); void _mongoc_scram_set_server_key (mongoc_scram_t *scram, const uint8_t *server_key, size_t len); void _mongoc_scram_set_salted_password (mongoc_scram_t *scram, const uint8_t *salted_password, size_t len); 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.3.4/src/libmongoc/src/mongoc/mongoc-scram.c0000664000175000017500000005643413210321137022353 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_CRYPTO #include #include "mongoc-error.h" #include "mongoc-scram-private.h" #include "mongoc-rand-private.h" #include "mongoc-util-private.h" #include "mongoc-trace-private.h" #include "mongoc-crypto-private.h" #include "mongoc-b64-private.h" #include "mongoc-memcmp-private.h" #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_set_client_key (mongoc_scram_t *scram, const uint8_t *client_key, size_t len) { BSON_ASSERT (scram); memcpy (scram->client_key, client_key, len); } void _mongoc_scram_set_server_key (mongoc_scram_t *scram, const uint8_t *server_key, size_t len) { BSON_ASSERT (scram); memcpy (scram->server_key, server_key, len); } void _mongoc_scram_set_salted_password (mongoc_scram_t *scram, const uint8_t *salted_password, size_t len) { BSON_ASSERT (scram); memcpy (scram->salted_password, salted_password, len); } void _mongoc_scram_init (mongoc_scram_t *scram) { BSON_ASSERT (scram); memset (scram, 0, sizeof *scram); mongoc_crypto_init (&scram->crypto); } 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); if (!scram->user) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: username is not set"); goto FAIL; } /* 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]; 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; mongoc_crypto_hmac_sha1 (&scram->crypto, password, password_len, start_key, sizeof (start_key), output); 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++) { mongoc_crypto_hmac_sha1 (&scram->crypto, password, password_len, intermediate_digest, sizeof (intermediate_digest), intermediate_digest); for (k = 0; k < MONGOC_SCRAM_HASH_SIZE; k++) { output[k] ^= intermediate_digest[k]; } } } static bool _mongoc_scram_generate_client_proof (mongoc_scram_t *scram, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen) { uint8_t stored_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t client_signature[MONGOC_SCRAM_HASH_SIZE]; unsigned char client_proof[MONGOC_SCRAM_HASH_SIZE]; int i; int r = 0; if (!*scram->client_key) { /* ClientKey := HMAC(saltedPassword, "Client Key") */ mongoc_crypto_hmac_sha1 (&scram->crypto, scram->salted_password, MONGOC_SCRAM_HASH_SIZE, (uint8_t *) MONGOC_SCRAM_CLIENT_KEY, strlen (MONGOC_SCRAM_CLIENT_KEY), scram->client_key); } /* StoredKey := H(client_key) */ mongoc_crypto_sha1 ( &scram->crypto, scram->client_key, MONGOC_SCRAM_HASH_SIZE, stored_key); /* ClientSignature := HMAC(StoredKey, AuthMessage) */ mongoc_crypto_hmac_sha1 (&scram->crypto, stored_key, MONGOC_SCRAM_HASH_SIZE, scram->auth_message, scram->auth_messagelen, client_signature); /* ClientProof := ClientKey XOR ClientSignature */ for (i = 0; i < MONGOC_SCRAM_HASH_SIZE; i++) { client_proof[i] = scram->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; } if (!*scram->salted_password) { _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) { char encoded_server_signature[MONGOC_SCRAM_B64_HASH_SIZE]; int32_t encoded_server_signature_len; uint8_t server_signature[MONGOC_SCRAM_HASH_SIZE]; if (!*scram->server_key) { /* ServerKey := HMAC(SaltedPassword, "Server Key") */ mongoc_crypto_hmac_sha1 (&scram->crypto, scram->salted_password, MONGOC_SCRAM_HASH_SIZE, (uint8_t *) MONGOC_SCRAM_SERVER_KEY, strlen (MONGOC_SCRAM_SERVER_KEY), scram->server_key); } /* ServerSignature := HMAC(ServerKey, AuthMessage) */ mongoc_crypto_hmac_sha1 (&scram->crypto, scram->server_key, MONGOC_SCRAM_HASH_SIZE, scram->auth_message, scram->auth_messagelen, server_signature); 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.3.4/src/libmongoc/src/mongoc/mongoc-secure-channel-private.h0000664000175000017500000000524513210321137025611 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_CHANNEL_PRIVATE_H #define MONGOC_SECURE_CHANNEL_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-ssl.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-tls-secure-channel-private.h" #define SECURITY_WIN32 #include #include #include BSON_BEGIN_DECLS char * _mongoc_secure_channel_extract_subject (const char *filename, const char *passphrase); bool mongoc_secure_channel_setup_ca ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); bool mongoc_secure_channel_setup_crl ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); size_t mongoc_secure_channel_read (mongoc_stream_tls_t *tls, void *data, size_t data_length); PCCERT_CONTEXT mongoc_secure_channel_setup_certificate ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt); /* Both schannel buffer sizes must be > 0 */ #define MONGOC_SCHANNEL_BUFFER_INIT_SIZE 4096 #define MONGOC_SCHANNEL_BUFFER_FREE_SIZE 1024 void _mongoc_secure_channel_init_sec_buffer (SecBuffer *buffer, unsigned long buf_type, void *buf_data_ptr, unsigned long buf_byte_size); void _mongoc_secure_channel_init_sec_buffer_desc (SecBufferDesc *desc, SecBuffer *buffer_array, unsigned long buffer_count); bool mongoc_secure_channel_handshake_step_1 (mongoc_stream_tls_t *tls, char *hostname); bool mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls, char *hostname); bool mongoc_secure_channel_handshake_step_3 (mongoc_stream_tls_t *tls, char *hostname); BSON_END_DECLS #endif /* MONGOC_SECURE_CHANNEL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-secure-channel.c0000664000175000017500000010245713210321137024137 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_CHANNEL #include #include "mongoc-log.h" #include "mongoc-trace-private.h" #include "mongoc-ssl.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-tls-private.h" #include "mongoc-secure-channel-private.h" #include "mongoc-stream-tls-secure-channel-private.h" #include "mongoc-errno-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-secure-channel" /* mingw doesn't define this */ #ifndef SECBUFFER_ALERT #define SECBUFFER_ALERT 17 #endif PCCERT_CONTEXT mongoc_secure_channel_setup_certificate_from_file (const char *filename) { char *pem; FILE *file; bool success; HCRYPTKEY hKey; long pem_length; HCRYPTPROV provider; CERT_BLOB public_blob; const char *pem_public; const char *pem_private; LPBYTE blob_private = NULL; PCCERT_CONTEXT cert = NULL; DWORD blob_private_len = 0; HCERTSTORE cert_store = NULL; DWORD encrypted_cert_len = 0; LPBYTE encrypted_cert = NULL; DWORD encrypted_private_len = 0; LPBYTE encrypted_private = NULL; file = fopen (filename, "rb"); if (!file) { MONGOC_ERROR ("Couldn't open file '%s'", filename); return false; } fseek (file, 0, SEEK_END); pem_length = ftell (file); fseek (file, 0, SEEK_SET); if (pem_length < 1) { MONGOC_ERROR ("Couldn't determine file size of '%s'", filename); return false; } pem = (char *) bson_malloc0 (pem_length); fread ((void *) pem, 1, pem_length, file); fclose (file); pem_public = strstr (pem, "-----BEGIN CERTIFICATE-----"); pem_private = strstr (pem, "-----BEGIN ENCRYPTED PRIVATE KEY-----"); if (pem_private) { MONGOC_ERROR ("Detected unsupported encrypted private key"); goto fail; } pem_private = strstr (pem, "-----BEGIN RSA PRIVATE KEY-----"); if (!pem_private) { pem_private = strstr (pem, "-----BEGIN PRIVATE KEY-----"); } if (!pem_private) { MONGOC_ERROR ("Can't find private key in '%s'", filename); goto fail; } public_blob.cbData = (DWORD) strlen (pem_public); public_blob.pbData = (BYTE *) pem_public; /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380264%28v=vs.85%29.aspx */ CryptQueryObject ( CERT_QUERY_OBJECT_BLOB, /* dwObjectType, blob or file */ &public_blob, /* pvObject, Unicode filename */ CERT_QUERY_CONTENT_FLAG_ALL, /* dwExpectedContentTypeFlags */ CERT_QUERY_FORMAT_FLAG_ALL, /* dwExpectedFormatTypeFlags */ 0, /* dwFlags, reserved for "future use" */ NULL, /* pdwMsgAndCertEncodingType, OUT, unused */ NULL, /* pdwContentType (dwExpectedContentTypeFlags), OUT, unused */ NULL, /* pdwFormatType (dwExpectedFormatTypeFlags,), OUT, unused */ NULL, /* phCertStore, OUT, HCERTSTORE.., unused, for now */ NULL, /* phMsg, OUT, HCRYPTMSG, only for PKC7, unused */ (const void **) &cert /* ppvContext, OUT, the Certificate Context */ ); if (!cert) { MONGOC_ERROR ("Failed to extract public key from '%s'. Error 0x%.8X", filename, GetLastError ()); goto fail; } /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380285%28v=vs.85%29.aspx */ success = CryptStringToBinaryA (pem_private, /* pszString */ 0, /* cchString */ CRYPT_STRING_BASE64HEADER, /* dwFlags */ NULL, /* pbBinary */ &encrypted_private_len, /* pcBinary, IN/OUT */ NULL, /* pdwSkip */ NULL); /* pdwFlags */ if (!success) { MONGOC_ERROR ("Failed to convert base64 private key. Error 0x%.8X", GetLastError ()); goto fail; } encrypted_private = (LPBYTE) bson_malloc0 (encrypted_private_len); success = CryptStringToBinaryA (pem_private, 0, CRYPT_STRING_BASE64HEADER, encrypted_private, &encrypted_private_len, NULL, NULL); if (!success) { MONGOC_ERROR ("Failed to convert base64 private key. Error 0x%.8X", GetLastError ()); goto fail; } /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379912%28v=vs.85%29.aspx */ success = CryptDecodeObjectEx ( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* dwCertEncodingType */ PKCS_RSA_PRIVATE_KEY, /* lpszStructType */ encrypted_private, /* pbEncoded */ encrypted_private_len, /* cbEncoded */ 0, /* dwFlags */ NULL, /* pDecodePara */ NULL, /* pvStructInfo */ &blob_private_len); /* pcbStructInfo */ if (!success) { LPTSTR msg = NULL; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError (), LANG_NEUTRAL, (LPTSTR) &msg, 0, NULL); MONGOC_ERROR ( "Failed to parse private key. %s (0x%.8X)", msg, GetLastError ()); LocalFree (msg); goto fail; } blob_private = (LPBYTE) bson_malloc0 (blob_private_len); success = CryptDecodeObjectEx (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, encrypted_private, encrypted_private_len, 0, NULL, blob_private, &blob_private_len); if (!success) { MONGOC_ERROR ("Failed to parse private key. Error 0x%.8X", GetLastError ()); goto fail; } /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886%28v=vs.85%29.aspx */ success = CryptAcquireContext (&provider, /* phProv */ NULL, /* pszContainer */ MS_ENHANCED_PROV, /* pszProvider */ PROV_RSA_FULL, /* dwProvType */ CRYPT_VERIFYCONTEXT); /* dwFlags */ if (!success) { MONGOC_ERROR ("CryptAcquireContext failed with error 0x%.8X", GetLastError ()); goto fail; } /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380207%28v=vs.85%29.aspx */ success = CryptImportKey (provider, /* hProv */ blob_private, /* pbData */ blob_private_len, /* dwDataLen */ 0, /* hPubKey */ 0, /* dwFlags */ &hKey); /* phKey, OUT */ if (!success) { MONGOC_ERROR ("CryptImportKey for private key failed with error 0x%.8X", GetLastError ()); goto fail; } /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa376573%28v=vs.85%29.aspx */ success = CertSetCertificateContextProperty ( cert, /* pCertContext */ CERT_KEY_PROV_HANDLE_PROP_ID, /* dwPropId */ 0, /* dwFlags */ (const void *) provider); /* pvData */ if (success) { TRACE ("Successfully loaded client certificate"); return cert; } MONGOC_ERROR ("Can't associate private key with public key: 0x%.8X", GetLastError ()); fail: SecureZeroMemory (pem, pem_length); bson_free (pem); if (encrypted_private) { SecureZeroMemory (encrypted_private, encrypted_private_len); bson_free (encrypted_private); } if (blob_private) { SecureZeroMemory (blob_private, blob_private_len); bson_free (blob_private); } return NULL; } PCCERT_CONTEXT mongoc_secure_channel_setup_certificate ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt) { return mongoc_secure_channel_setup_certificate_from_file (opt->pem_file); } void _bson_append_szoid (bson_string_t *retval, PCCERT_CONTEXT cert, const char *label, void *oid) { DWORD oid_len = CertGetNameString (cert, CERT_NAME_ATTR_TYPE, 0, oid, NULL, 0); if (oid_len > 1) { char *tmp = bson_malloc0 (oid_len); CertGetNameString (cert, CERT_NAME_ATTR_TYPE, 0, oid, tmp, oid_len); bson_string_append_printf (retval, "%s%s", label, tmp); bson_free (tmp); } } char * _mongoc_secure_channel_extract_subject (const char *filename, const char *passphrase) { bson_string_t *retval; PCCERT_CONTEXT cert; cert = mongoc_secure_channel_setup_certificate_from_file (filename); if (!cert) { return NULL; } retval = bson_string_new (""); ; _bson_append_szoid (retval, cert, "C=", szOID_COUNTRY_NAME); _bson_append_szoid (retval, cert, ",ST=", szOID_STATE_OR_PROVINCE_NAME); _bson_append_szoid (retval, cert, ",L=", szOID_LOCALITY_NAME); _bson_append_szoid (retval, cert, ",O=", szOID_ORGANIZATION_NAME); _bson_append_szoid (retval, cert, ",OU=", szOID_ORGANIZATIONAL_UNIT_NAME); _bson_append_szoid (retval, cert, ",CN=", szOID_COMMON_NAME); _bson_append_szoid (retval, cert, ",STREET=", szOID_STREET_ADDRESS); return bson_string_free (retval, false); } bool mongoc_secure_channel_setup_ca ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt) { FILE *file; long length; const char *pem_key; HCERTSTORE cert_store = NULL; PCCERT_CONTEXT cert = NULL; DWORD encrypted_cert_len = 0; LPBYTE encrypted_cert = NULL; file = fopen (opt->ca_file, "rb"); if (!file) { MONGOC_WARNING ("Couldn't open file '%s'", opt->ca_file); return false; } fseek (file, 0, SEEK_END); length = ftell (file); fseek (file, 0, SEEK_SET); if (length < 1) { MONGOC_WARNING ("Couldn't determine file size of '%s'", opt->ca_file); return false; } pem_key = (const char *) bson_malloc0 (length); fread ((void *) pem_key, 1, length, file); fclose (file); /* If we have private keys or other fuzz, seek to the good stuff */ pem_key = strstr (pem_key, "-----BEGIN CERTIFICATE-----"); /*printf ("%s\n", pem_key);*/ if (!pem_key) { MONGOC_WARNING ("Couldn't find certificate in '%d'", opt->ca_file); return false; } if (!CryptStringToBinaryA (pem_key, 0, CRYPT_STRING_BASE64HEADER, NULL, &encrypted_cert_len, NULL, NULL)) { MONGOC_ERROR ("Failed to convert BASE64 public key. Error 0x%.8X", GetLastError ()); return false; } encrypted_cert = (LPBYTE) LocalAlloc (0, encrypted_cert_len); if (!CryptStringToBinaryA (pem_key, 0, CRYPT_STRING_BASE64HEADER, encrypted_cert, &encrypted_cert_len, NULL, NULL)) { MONGOC_ERROR ("Failed to convert BASE64 public key. Error 0x%.8X", GetLastError ()); return false; } cert = CertCreateCertificateContext ( X509_ASN_ENCODING, encrypted_cert, encrypted_cert_len); if (!cert) { MONGOC_WARNING ("Could not convert certificate"); return false; } cert_store = CertOpenStore ( CERT_STORE_PROV_SYSTEM, /* provider */ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */ 0, /* unused */ CERT_SYSTEM_STORE_LOCAL_MACHINE, /* dwFlags */ L"Root"); /* system store name. "My" or "Root" */ if (cert_store == NULL) { MONGOC_ERROR ("Error opening certificate store"); return false; } if (CertAddCertificateContextToStore ( cert_store, cert, CERT_STORE_ADD_USE_EXISTING, NULL)) { TRACE ("Added the certificate !"); CertCloseStore (cert_store, 0); return true; } MONGOC_WARNING ("Failed adding the cert"); CertCloseStore (cert_store, 0); return false; } bool mongoc_secure_channel_setup_crl ( mongoc_stream_tls_secure_channel_t *secure_channel, mongoc_ssl_opt_t *opt) { HCERTSTORE cert_store = NULL; PCCERT_CONTEXT cert = NULL; LPWSTR str; int chars; chars = MultiByteToWideChar (CP_ACP, 0, opt->crl_file, -1, NULL, 0); if (chars < 1) { MONGOC_WARNING ("Can't determine opt->crl_file length"); return false; } str = (LPWSTR) bson_malloc0 (chars); MultiByteToWideChar (CP_ACP, 0, opt->crl_file, -1, str, chars); /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa380264%28v=vs.85%29.aspx */ CryptQueryObject ( CERT_QUERY_OBJECT_FILE, /* dwObjectType, blob or file */ str, /* pvObject, Unicode filename */ CERT_QUERY_CONTENT_FLAG_CRL, /* dwExpectedContentTypeFlags */ CERT_QUERY_FORMAT_FLAG_ALL, /* dwExpectedFormatTypeFlags */ 0, /* dwFlags, reserved for "future use" */ NULL, /* pdwMsgAndCertEncodingType, OUT, unused */ NULL, /* pdwContentType (dwExpectedContentTypeFlags), OUT, unused */ NULL, /* pdwFormatType (dwExpectedFormatTypeFlags,), OUT, unused */ NULL, /* phCertStore, OUT, HCERTSTORE.., unused, for now */ NULL, /* phMsg, OUT, HCRYPTMSG, only for PKC7, unused */ (const void **) &cert /* ppvContext, OUT, the Certificate Context */ ); bson_free (str); if (!cert) { MONGOC_WARNING ("Can't extract CRL from '%s'", opt->crl_file); return false; } cert_store = CertOpenStore ( CERT_STORE_PROV_SYSTEM, /* provider */ X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, /* certificate encoding */ 0, /* unused */ CERT_SYSTEM_STORE_LOCAL_MACHINE, /* dwFlags */ L"Root"); /* system store name. "My" or "Root" */ if (cert_store == NULL) { MONGOC_ERROR ("Error opening certificate store"); CertFreeCertificateContext (cert); return false; } if (CertAddCertificateContextToStore ( cert_store, cert, CERT_STORE_ADD_USE_EXISTING, NULL)) { TRACE ("Added the certificate !"); CertFreeCertificateContext (cert); CertCloseStore (cert_store, 0); return true; } MONGOC_WARNING ("Failed adding the cert"); CertFreeCertificateContext (cert); CertCloseStore (cert_store, 0); return false; } size_t mongoc_secure_channel_read (mongoc_stream_tls_t *tls, void *data, size_t data_length) { ssize_t length; errno = 0; TRACE ("Wanting to read: %d", data_length); /* 4th argument is minimum bytes, while the data_length is the * size of the buffer. We are totally fine with just one TLS record (few *bytes) **/ length = mongoc_stream_read ( tls->base_stream, data, data_length, 0, tls->timeout_msec); TRACE ("Got %d", length); if (length > 0) { return length; } return 0; } size_t mongoc_secure_channel_write (mongoc_stream_tls_t *tls, const void *data, size_t data_length) { ssize_t length; errno = 0; TRACE ("Wanting to write: %d", data_length); length = mongoc_stream_write ( tls->base_stream, (void *) data, data_length, tls->timeout_msec); TRACE ("Wrote: %d", length); return length; } /** * The follow functions comes from one of my favorite project, cURL! * Thank you so much for having gone through the Secure Channel pain for me. * * * Copyright (C) 2012 - 2015, Marc Hoersken, * Copyright (C) 2012, Mark Salisbury, * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ***************************************************************************/ /* * Based upon the PolarSSL implementation in polarssl.c and polarssl.h: * Copyright (C) 2010, 2011, Hoi-Ho Chan, * * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. * * Thanks for code and inspiration! */ void _mongoc_secure_channel_init_sec_buffer (SecBuffer *buffer, unsigned long buf_type, void *buf_data_ptr, unsigned long buf_byte_size) { buffer->cbBuffer = buf_byte_size; buffer->BufferType = buf_type; buffer->pvBuffer = buf_data_ptr; } void _mongoc_secure_channel_init_sec_buffer_desc (SecBufferDesc *desc, SecBuffer *buffer_array, unsigned long buffer_count) { desc->ulVersion = SECBUFFER_VERSION; desc->pBuffers = buffer_array; desc->cBuffers = buffer_count; } bool mongoc_secure_channel_handshake_step_1 (mongoc_stream_tls_t *tls, char *hostname) { SecBuffer outbuf; ssize_t written = -1; SecBufferDesc outbuf_desc; SECURITY_STATUS sspi_status = SEC_E_OK; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; TRACE ("SSL/TLS connection with '%s' (step 1/3)", hostname); /* setup output buffer */ _mongoc_secure_channel_init_sec_buffer (&outbuf, SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, &outbuf, 1); /* setup request flags */ secure_channel->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM; /* allocate memory for the security context handle */ secure_channel->ctxt = (mongoc_secure_channel_ctxt *) bson_malloc0 ( sizeof (mongoc_secure_channel_ctxt)); /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */ sspi_status = InitializeSecurityContext ( &secure_channel->cred->cred_handle, /* phCredential */ NULL, /* phContext */ hostname, /* pszTargetName */ secure_channel->req_flags, /* fContextReq */ 0, /* Reserved1, must be 0 */ 0, /* TargetDataRep, unused */ NULL, /* pInput */ 0, /* Reserved2, must be 0 */ &secure_channel->ctxt->ctxt_handle, /* phNewContext OUT param */ &outbuf_desc, /* pOutput OUT param */ &secure_channel->ret_flags, /* pfContextAttr OUT param */ &secure_channel->ctxt->time_stamp /* ptsExpiry OUT param */ ); if (sspi_status != SEC_I_CONTINUE_NEEDED) { MONGOC_ERROR ("initial InitializeSecurityContext failed: %d", sspi_status); return false; } TRACE ("sending initial handshake data: sending %lu bytes...", outbuf.cbBuffer); /* send initial handshake data which is now stored in output buffer */ written = mongoc_secure_channel_write (tls, outbuf.pvBuffer, outbuf.cbBuffer); FreeContextBuffer (outbuf.pvBuffer); if (outbuf.cbBuffer != (size_t) written) { MONGOC_ERROR ("failed to send initial handshake data: " "sent %zd of %lu bytes", written, outbuf.cbBuffer); return false; } TRACE ("sent initial handshake data: sent %zd bytes", written); secure_channel->recv_unrecoverable_err = 0; secure_channel->recv_sspi_close_notify = false; secure_channel->recv_connection_closed = false; /* continue to second handshake step */ secure_channel->connecting_state = ssl_connect_2; return true; } bool mongoc_secure_channel_handshake_step_2 (mongoc_stream_tls_t *tls, char *hostname) { mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; SECURITY_STATUS sspi_status = SEC_E_OK; unsigned char *reallocated_buffer; ssize_t nread = -1, written = -1; size_t reallocated_length; SecBufferDesc outbuf_desc; SecBufferDesc inbuf_desc; SecBuffer outbuf[3]; SecBuffer inbuf[2]; bool doread; int i; doread = (secure_channel->connecting_state != ssl_connect_2_writing) ? true : false; TRACE ("SSL/TLS connection with endpoint (step 2/3)"); if (!secure_channel->cred || !secure_channel->ctxt) { return false; } /* buffer to store previously received and decrypted data */ if (secure_channel->decdata_buffer == NULL) { secure_channel->decdata_offset = 0; secure_channel->decdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE; secure_channel->decdata_buffer = bson_malloc0 (secure_channel->decdata_length); } /* buffer to store previously received and encrypted data */ if (secure_channel->encdata_buffer == NULL) { secure_channel->encdata_offset = 0; secure_channel->encdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE; secure_channel->encdata_buffer = bson_malloc0 (secure_channel->encdata_length); } /* if we need a bigger buffer to read a full message, increase buffer now */ if (secure_channel->encdata_length - secure_channel->encdata_offset < MONGOC_SCHANNEL_BUFFER_FREE_SIZE) { /* increase internal encrypted data buffer */ reallocated_length = secure_channel->encdata_offset + MONGOC_SCHANNEL_BUFFER_FREE_SIZE; reallocated_buffer = bson_realloc (secure_channel->encdata_buffer, reallocated_length); secure_channel->encdata_buffer = reallocated_buffer; secure_channel->encdata_length = reallocated_length; } for (;;) { if (doread) { /* read encrypted handshake data from socket */ nread = mongoc_secure_channel_read ( tls, (char *) (secure_channel->encdata_buffer + secure_channel->encdata_offset), secure_channel->encdata_length - secure_channel->encdata_offset); if (!nread) { if (MONGOC_ERRNO_IS_AGAIN (errno)) { if (secure_channel->connecting_state != ssl_connect_2_writing) { secure_channel->connecting_state = ssl_connect_2_reading; } TRACE ("failed to receive handshake, need more data"); return true; } MONGOC_ERROR ( "failed to receive handshake, SSL/TLS connection failed"); return false; } /* increase encrypted data buffer offset */ secure_channel->encdata_offset += nread; } TRACE ("encrypted data buffer: offset %zu length %zu", secure_channel->encdata_offset, secure_channel->encdata_length); /* setup input buffers */ _mongoc_secure_channel_init_sec_buffer ( &inbuf[0], SECBUFFER_TOKEN, malloc (secure_channel->encdata_offset), (unsigned long) (secure_channel->encdata_offset & (size_t) 0xFFFFFFFFUL)); _mongoc_secure_channel_init_sec_buffer ( &inbuf[1], SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer_desc (&inbuf_desc, inbuf, 2); /* setup output buffers */ _mongoc_secure_channel_init_sec_buffer ( &outbuf[0], SECBUFFER_TOKEN, NULL, 0); _mongoc_secure_channel_init_sec_buffer ( &outbuf[1], SECBUFFER_ALERT, NULL, 0); _mongoc_secure_channel_init_sec_buffer ( &outbuf[2], SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, outbuf, 3); if (inbuf[0].pvBuffer == NULL) { MONGOC_ERROR ("unable to allocate memory"); return false; } /* copy received handshake data into input buffer */ memcpy (inbuf[0].pvBuffer, secure_channel->encdata_buffer, secure_channel->encdata_offset); /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */ sspi_status = InitializeSecurityContext (&secure_channel->cred->cred_handle, &secure_channel->ctxt->ctxt_handle, hostname, secure_channel->req_flags, 0, 0, &inbuf_desc, 0, NULL, &outbuf_desc, &secure_channel->ret_flags, &secure_channel->ctxt->time_stamp); /* free buffer for received handshake data */ free (inbuf[0].pvBuffer); /* check if the handshake was incomplete */ if (sspi_status == SEC_E_INCOMPLETE_MESSAGE) { secure_channel->connecting_state = ssl_connect_2_reading; TRACE ("received incomplete message, need more data"); return true; } /* If the server has requested a client certificate, attempt to continue * the handshake without one. This will allow connections to servers which * request a client certificate but do not require it. */ if (sspi_status == SEC_I_INCOMPLETE_CREDENTIALS && !(secure_channel->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { secure_channel->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; secure_channel->connecting_state = ssl_connect_2_writing; TRACE ("a client certificate has been requested"); return true; } /* check if the handshake needs to be continued */ if (sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) { for (i = 0; i < 3; i++) { /* search for handshake tokens that need to be send */ if (outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) { TRACE ("sending next handshake data: sending %lu bytes...", outbuf[i].cbBuffer); /* send handshake token to server */ written = mongoc_secure_channel_write ( tls, outbuf[i].pvBuffer, outbuf[i].cbBuffer); if (outbuf[i].cbBuffer != (size_t) written) { MONGOC_ERROR ("failed to send next handshake data: " "sent %zd of %lu bytes", written, outbuf[i].cbBuffer); return false; } } /* free obsolete buffer */ if (outbuf[i].pvBuffer != NULL) { FreeContextBuffer (outbuf[i].pvBuffer); } } } else { switch (sspi_status) { case SEC_E_WRONG_PRINCIPAL: MONGOC_ERROR ("SSL Certification verification failed: hostname " "doesn't match certificate"); break; case SEC_E_UNTRUSTED_ROOT: MONGOC_ERROR ("SSL Certification verification failed: Untrusted " "root certificate"); break; case SEC_E_CERT_EXPIRED: MONGOC_ERROR ("SSL Certification verification failed: certificate " "has expired"); break; case CRYPT_E_NO_REVOCATION_CHECK: /* This seems to be raised also when hostname doesn't match the * certificate */ MONGOC_ERROR ("SSL Certification verification failed: failed " "revocation/hostname check"); break; case SEC_E_INSUFFICIENT_MEMORY: case SEC_E_INTERNAL_ERROR: case SEC_E_INVALID_HANDLE: case SEC_E_INVALID_TOKEN: case SEC_E_LOGON_DENIED: case SEC_E_NO_AUTHENTICATING_AUTHORITY: case SEC_E_NO_CREDENTIALS: case SEC_E_TARGET_UNKNOWN: case SEC_E_UNSUPPORTED_FUNCTION: #ifdef SEC_E_APPLICATION_PROTOCOL_MISMATCH /* Not available in VS2010 */ case SEC_E_APPLICATION_PROTOCOL_MISMATCH: #endif default: { LPTSTR msg = NULL; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError (), LANG_NEUTRAL, (LPTSTR) &msg, 0, NULL); MONGOC_ERROR ("Failed to initialize security context, error code: " "0x%04X%04X: %s", (sspi_status >> 16) & 0xffff, sspi_status & 0xffff, msg); LocalFree (msg); } } return false; } /* check if there was additional remaining encrypted data */ if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { TRACE ("encrypted data length: %lu", inbuf[1].cbBuffer); /* * There are two cases where we could be getting extra data here: * 1) If we're renegotiating a connection and the handshake is already * complete (from the server perspective), it can encrypted app data * (not handshake data) in an extra buffer at this point. * 2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a * connection and this extra data is part of the handshake. * We should process the data immediately; waiting for the socket to * be ready may fail since the server is done sending handshake data. */ /* check if the remaining data is less than the total amount * and therefore begins after the already processed data */ if (secure_channel->encdata_offset > inbuf[1].cbBuffer) { memmove (secure_channel->encdata_buffer, (secure_channel->encdata_buffer + secure_channel->encdata_offset) - inbuf[1].cbBuffer, inbuf[1].cbBuffer); secure_channel->encdata_offset = inbuf[1].cbBuffer; if (sspi_status == SEC_I_CONTINUE_NEEDED) { doread = FALSE; continue; } } } else { secure_channel->encdata_offset = 0; } break; } /* check if the handshake needs to be continued */ if (sspi_status == SEC_I_CONTINUE_NEEDED) { secure_channel->connecting_state = ssl_connect_2_reading; return true; } /* check if the handshake is complete */ if (sspi_status == SEC_E_OK) { secure_channel->connecting_state = ssl_connect_3; TRACE ("SSL/TLS handshake complete\n"); } return true; } bool mongoc_secure_channel_handshake_step_3 (mongoc_stream_tls_t *tls, char *hostname) { mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; BSON_ASSERT (ssl_connect_3 == secure_channel->connecting_state); TRACE ("SSL/TLS connection with %s (step 3/3)\n", hostname); if (!secure_channel->cred) { return false; } /* check if the required context attributes are met */ if (secure_channel->ret_flags != secure_channel->req_flags) { MONGOC_ERROR ("Failed handshake"); return false; } secure_channel->connecting_state = ssl_connect_done; return true; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-secure-transport-private.h0000664000175000017500000000327313210321137026234 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_TRANSPORT_PRIVATE_H #define MONGOC_SECURE_TRANSPORT_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-ssl.h" #include "mongoc-stream-tls-secure-transport-private.h" #include BSON_BEGIN_DECLS char * _mongoc_secure_transport_extract_subject (const char *filename, const char *passphrase); OSStatus mongoc_secure_transport_write (SSLConnectionRef connection, const void *data, size_t *data_length); OSStatus mongoc_secure_transport_read (SSLConnectionRef connection, void *data, size_t *data_length); bool mongoc_secure_transport_setup_ca ( mongoc_stream_tls_secure_transport_t *secure_transport, mongoc_ssl_opt_t *opt); bool mongoc_secure_transport_setup_certificate ( mongoc_stream_tls_secure_transport_t *secure_transport, mongoc_ssl_opt_t *opt); BSON_END_DECLS #endif /* MONGOC_SECURE_TRANSPORT_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-secure-transport.c0000664000175000017500000003303613210321137024557 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_TRANSPORT #include #include "mongoc-log.h" #include "mongoc-trace-private.h" #include "mongoc-ssl.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-tls-private.h" #include "mongoc-secure-transport-private.h" #include "mongoc-stream-tls-secure-transport-private.h" #include #include #include #include #include #include #include #include /* Jailbreak Darwin Private API */ SecIdentityRef SecIdentityCreate (CFAllocatorRef allocator, SecCertificateRef certificate, SecKeyRef privateKey); #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-secure_transport" void _bson_append_cftyperef (bson_string_t *retval, const char *label, CFTypeRef str) { if (str && CFGetTypeID (str) == CFStringGetTypeID ()) { CFIndex length = CFStringGetLength (str); CFStringEncoding encoding = kCFStringEncodingASCII; CFIndex maxSize = CFStringGetMaximumSizeForEncoding (length, encoding) + 1; char *cs = bson_malloc ((size_t) maxSize); if (CFStringGetCString (str, cs, maxSize, encoding)) { bson_string_append_printf (retval, "%s%s", label, cs); } else { bson_string_append_printf (retval, "%s(null)", label); } bson_free (cs); } } CFTypeRef _mongoc_secure_transport_dict_get (CFArrayRef values, CFStringRef label) { if (!values || CFGetTypeID (values) != CFArrayGetTypeID ()) { return NULL; } for (CFIndex i = 0; i < CFArrayGetCount (values); ++i) { CFStringRef item_label; CFDictionaryRef item = CFArrayGetValueAtIndex (values, i); if (CFGetTypeID (item) != CFDictionaryGetTypeID ()) { continue; } item_label = CFDictionaryGetValue (item, kSecPropertyKeyLabel); if (item_label && CFStringCompare (item_label, label, 0) == kCFCompareEqualTo) { return CFDictionaryGetValue (item, kSecPropertyKeyValue); } } return NULL; } char * _mongoc_secure_transport_RFC2253_from_cert (SecCertificateRef cert) { CFTypeRef value; bson_string_t *retval; CFTypeRef subject_name; CFDictionaryRef cert_dict; cert_dict = SecCertificateCopyValues (cert, NULL, NULL); if (!cert_dict) { return NULL; } subject_name = CFDictionaryGetValue (cert_dict, kSecOIDX509V1SubjectName); if (!subject_name) { CFRelease (cert_dict); return NULL; } subject_name = CFDictionaryGetValue (subject_name, kSecPropertyKeyValue); if (!subject_name) { CFRelease (cert_dict); return NULL; } retval = bson_string_new (""); ; value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCountryName); _bson_append_cftyperef (retval, "C=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDStateProvinceName); _bson_append_cftyperef (retval, ",ST=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDLocalityName); _bson_append_cftyperef (retval, ",L=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDOrganizationName); _bson_append_cftyperef (retval, ",O=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDOrganizationalUnitName); if (value) { /* Can be either one unit name, or array of unit names */ if (CFGetTypeID (value) == CFStringGetTypeID ()) { _bson_append_cftyperef (retval, ",OU=", value); } else if (CFGetTypeID (value) == CFArrayGetTypeID ()) { CFIndex len = CFArrayGetCount (value); if (len > 0) { _bson_append_cftyperef ( retval, ",OU=", CFArrayGetValueAtIndex (value, 0)); } if (len > 1) { _bson_append_cftyperef ( retval, ",", CFArrayGetValueAtIndex (value, 1)); } if (len > 2) { _bson_append_cftyperef ( retval, ",", CFArrayGetValueAtIndex (value, 2)); } } } value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCommonName); _bson_append_cftyperef (retval, ",CN=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDStreetAddress); _bson_append_cftyperef (retval, ",STREET", value); CFRelease (cert_dict); return bson_string_free (retval, false); } bool _mongoc_secure_transport_import_pem (const char *filename, const char *passphrase, CFArrayRef *items, SecExternalItemType *type) { SecExternalFormat format = kSecFormatPEMSequence; SecItemImportExportKeyParameters params; SecTransformRef sec_transform; CFReadStreamRef read_stream; CFDataRef dataref; CFErrorRef error; CFURLRef url; OSStatus res; if (!filename) { MONGOC_INFO ("%s", "No certificate provided"); return false; } params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; params.flags = 0; params.passphrase = NULL; params.alertTitle = NULL; params.alertPrompt = NULL; params.accessRef = NULL; params.keyUsage = NULL; params.keyAttributes = NULL; if (passphrase) { params.passphrase = CFStringCreateWithCString ( kCFAllocatorDefault, passphrase, kCFStringEncodingUTF8); } url = CFURLCreateFromFileSystemRepresentation ( kCFAllocatorDefault, (const UInt8 *) filename, strlen (filename), false); read_stream = CFReadStreamCreateWithFile (kCFAllocatorDefault, url); sec_transform = SecTransformCreateReadTransformWithReadStream (read_stream); dataref = SecTransformExecute (sec_transform, &error); if (error) { CFStringRef str = CFErrorCopyDescription (error); MONGOC_ERROR ( "Failed importing PEM '%s': %s", filename, CFStringGetCStringPtr (str, CFStringGetFastestEncoding (str))); CFRelease (str); CFRelease (sec_transform); CFRelease (read_stream); CFRelease (url); if (passphrase) { CFRelease (params.passphrase); } return false; } res = SecItemImport ( dataref, CFSTR (".pem"), &format, type, 0, ¶ms, NULL, items); CFRelease (dataref); CFRelease (sec_transform); CFRelease (read_stream); CFRelease (url); if (passphrase) { CFRelease (params.passphrase); } if (res) { MONGOC_ERROR ("Failed importing PEM '%s' (code: %d)", filename, res); return false; } return true; } char * _mongoc_secure_transport_extract_subject (const char *filename, const char *passphrase) { bool success; char *retval = NULL; CFArrayRef items = NULL; SecExternalItemType type = kSecItemTypeCertificate; success = _mongoc_secure_transport_import_pem (filename, passphrase, &items, &type); if (!success) { return NULL; } if (type == kSecItemTypeAggregate) { for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); if (item_id == SecCertificateGetTypeID ()) { retval = _mongoc_secure_transport_RFC2253_from_cert ( (SecCertificateRef) CFArrayGetValueAtIndex (items, i)); break; } } } else if (type == kSecItemTypeCertificate) { retval = _mongoc_secure_transport_RFC2253_from_cert ((SecCertificateRef) items); } if (items) { CFRelease (items); } return retval; } bool mongoc_secure_transport_setup_certificate ( mongoc_stream_tls_secure_transport_t *secure_transport, mongoc_ssl_opt_t *opt) { bool success; CFArrayRef items; SecIdentityRef id; SecKeyRef key = NULL; SecCertificateRef cert = NULL; SecExternalItemType type = kSecItemTypeCertificate; if (!opt->pem_file) { MONGOC_INFO ( "No private key provided, the server won't be able to verify us"); return false; } success = _mongoc_secure_transport_import_pem ( opt->pem_file, opt->pem_pwd, &items, &type); if (!success) { MONGOC_ERROR ("Can't find certificate in: '%s'", opt->pem_file); return false; } if (type != kSecItemTypeAggregate) { MONGOC_ERROR ("Cannot work with keys of type \"%d\". Please file a JIRA", type); CFRelease (items); return false; } for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); if (item_id == SecCertificateGetTypeID ()) { cert = (SecCertificateRef) CFArrayGetValueAtIndex (items, i); } else if (item_id == SecKeyGetTypeID ()) { key = (SecKeyRef) CFArrayGetValueAtIndex (items, i); } } if (!cert || !key) { MONGOC_ERROR ("Couldn't find valid private key"); CFRelease (items); return false; } id = SecIdentityCreate (kCFAllocatorDefault, cert, key); secure_transport->my_cert = CFArrayCreateMutableCopy (kCFAllocatorDefault, (CFIndex) 2, items); CFArraySetValueAtIndex (secure_transport->my_cert, 0, id); CFArraySetValueAtIndex (secure_transport->my_cert, 1, cert); /* * Secure Transport assumes the following: * * The certificate references remain valid for the lifetime of the * session. * * The identity specified in certRefs[0] is capable of signing. */ success = !SSLSetCertificate (secure_transport->ssl_ctx_ref, secure_transport->my_cert); MONGOC_DEBUG ("Setting client certificate %s", success ? "succeeded" : "failed"); CFRelease (items); return true; } bool mongoc_secure_transport_setup_ca ( mongoc_stream_tls_secure_transport_t *secure_transport, mongoc_ssl_opt_t *opt) { if (opt->ca_file) { CFArrayRef items; SecExternalItemType type = kSecItemTypeCertificate; bool success = _mongoc_secure_transport_import_pem ( opt->ca_file, NULL, &items, &type); if (!success) { MONGOC_ERROR ("Can't find certificate in \"%s\"", opt->ca_file); return false; } if (type == kSecItemTypeAggregate) { CFMutableArrayRef anchors = CFArrayCreateMutable ( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); for (CFIndex i = 0; i < CFArrayGetCount (items); ++i) { CFTypeID item_id = CFGetTypeID (CFArrayGetValueAtIndex (items, i)); if (item_id == SecCertificateGetTypeID ()) { CFArrayAppendValue (anchors, CFArrayGetValueAtIndex (items, i)); } } secure_transport->anchors = CFRetain (anchors); CFRelease (items); } else if (type == kSecItemTypeCertificate) { secure_transport->anchors = CFRetain (items); } /* This should be SSLSetCertificateAuthorities But the /TLS/ tests fail * when it is */ success = !SSLSetTrustedRoots ( secure_transport->ssl_ctx_ref, secure_transport->anchors, true); MONGOC_DEBUG ("Setting certificate authority %s (%s)", success ? "succeeded" : "failed", opt->ca_file); return true; } MONGOC_INFO ("No CA provided, using defaults"); return false; } OSStatus mongoc_secure_transport_read (SSLConnectionRef connection, void *data, size_t *data_length) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) connection; ssize_t length; ENTRY; errno = 0; /* 4 arguments is *min_bytes* -- This is not a negotiation. * Secure Transport wants all or nothing. We must continue reading until * we get this amount, or timeout */ length = mongoc_stream_read ( tls->base_stream, data, *data_length, *data_length, tls->timeout_msec); if (length > 0) { *data_length = length; RETURN (noErr); } if (length == 0) { RETURN (errSSLClosedGraceful); } switch (errno) { case ENOENT: RETURN (errSSLClosedGraceful); break; case ECONNRESET: RETURN (errSSLClosedAbort); break; case EAGAIN: RETURN (errSSLWouldBlock); break; default: RETURN (-36); /* ioErr */ break; } } OSStatus mongoc_secure_transport_write (SSLConnectionRef connection, const void *data, size_t *data_length) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) connection; ssize_t length; ENTRY; errno = 0; length = mongoc_stream_write ( tls->base_stream, (void *) data, *data_length, tls->timeout_msec); if (length >= 0) { *data_length = length; RETURN (noErr); } switch (errno) { case EAGAIN: RETURN (errSSLWouldBlock); break; default: RETURN (-36); /* ioErr */ break; } } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-server-description-private.h0000664000175000017500000001020613210321137026535 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 #define MONGOC_IDLE_WRITE_PERIOD_MS 10 * 1000 /* 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_msec; int64_t last_update_time_usec; bson_t last_is_master; bool has_is_master; const char *connection_address; const char *me; /* whether an APM server-opened callback has been fired before */ bool opened; 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; int64_t last_write_date_ms; #ifdef MONGOC_ENABLE_COMPRESSION bson_t compressors; #endif }; 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 rtt_msec); void mongoc_server_description_handle_ismaster (mongoc_server_description_t *sd, const bson_t *reply, int64_t rtt_msec, const bson_error_t *error /* IN */); void mongoc_server_description_filter_stale (mongoc_server_description_t **sds, size_t sds_len, mongoc_server_description_t *primary, int64_t heartbeat_frequency_ms, const mongoc_read_prefs_t *read_prefs); void mongoc_server_description_filter_tags ( mongoc_server_description_t **descriptions, size_t description_len, const mongoc_read_prefs_t *read_prefs); #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-server-description.c0000664000175000017500000006770413210321137025077 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" #include "mongoc-host-list.h" #include "mongoc-host-list-private.h" #include "mongoc-read-prefs.h" #include "mongoc-read-prefs-private.h" #include "mongoc-server-description-private.h" #include "mongoc-trace-private.h" #include "mongoc-uri.h" #include "mongoc-util-private.h" #include "mongoc-compression-private.h" #include #define ALPHA 0.2 static bson_oid_t kObjectIdZero = {{0}}; static bool _match_tag_set (const mongoc_server_description_t *sd, bson_iter_t *tag_set_iter); /* 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); memset (&sd->error, 0, sizeof sd->error); 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; sd->last_write_date_ms = -1; /* 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; sd->last_update_time_usec = bson_get_monotonic_time (); bson_init (&sd->hosts); bson_init (&sd->passives); bson_init (&sd->arbiters); bson_init (&sd->tags); #ifdef MONGOC_ENABLE_COMPRESSION bson_init (&sd->compressors); #endif sd->me = NULL; sd->current_primary = NULL; sd->set_version = MONGOC_NO_SET_VERSION; bson_oid_copy_unsafe (&kObjectIdZero, &sd->election_id); } /* *-------------------------------------------------------------------------- * * 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); sd->id = id; sd->type = MONGOC_SERVER_UNKNOWN; sd->round_trip_time_msec = -1; 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; bson_init (&sd->last_is_master); mongoc_server_description_reset (sd); 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 (const mongoc_server_description_t *description) { return description->id; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_host -- * * Return a reference to the host associated with this server description. * * Returns: * This server description's host, a mongoc_host_list_t * you must * not modify or free. * *-------------------------------------------------------------------------- */ mongoc_host_list_t * mongoc_server_description_host (const mongoc_server_description_t *description) { return &((mongoc_server_description_t *) description)->host; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_round_trip_time -- * * Get the round trip time of this server, which is the client's * measurement of the duration of an "ismaster" command. * * Returns: * The server's round trip time in milliseconds. * *-------------------------------------------------------------------------- */ int64_t mongoc_server_description_round_trip_time ( const mongoc_server_description_t *description) { return description->round_trip_time_msec; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_type -- * * Get this server's type, one of the types defined in the Server * Discovery And Monitoring Spec. * * Returns: * A string. * *-------------------------------------------------------------------------- */ const char * mongoc_server_description_type (const mongoc_server_description_t *description) { switch (description->type) { case MONGOC_SERVER_UNKNOWN: return "Unknown"; case MONGOC_SERVER_STANDALONE: return "Standalone"; case MONGOC_SERVER_MONGOS: return "Mongos"; case MONGOC_SERVER_POSSIBLE_PRIMARY: return "PossiblePrimary"; case MONGOC_SERVER_RS_PRIMARY: return "RSPrimary"; case MONGOC_SERVER_RS_SECONDARY: return "RSSecondary"; case MONGOC_SERVER_RS_ARBITER: return "RSArbiter"; case MONGOC_SERVER_RS_OTHER: return "RSOther"; case MONGOC_SERVER_RS_GHOST: return "RSGhost"; case MONGOC_SERVER_DESCRIPTION_TYPES: default: MONGOC_ERROR ("Invalid mongoc_server_description_t type"); return "Invalid"; } } /* *-------------------------------------------------------------------------- * * mongoc_server_description_ismaster -- * * Return this server's most recent "ismaster" command response. * * Returns: * A reference to a BSON document, owned by the server description. * *-------------------------------------------------------------------------- */ const bson_t * mongoc_server_description_ismaster ( const mongoc_server_description_t *description) { return &description->last_is_master; } /* *-------------------------------------------------------------------------- * * 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 rtt_msec) { if (server->round_trip_time_msec == -1) { server->round_trip_time_msec = rtt_msec; } else { server->round_trip_time_msec = (int64_t) ( ALPHA * rtt_msec + (1 - ALPHA) * server->round_trip_time_msec); } } static void _mongoc_server_description_set_error (mongoc_server_description_t *sd, const bson_error_t *error) { if (error && error->code) { memcpy (&sd->error, error, sizeof (bson_error_t)); } else { bson_set_error (&sd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "unknown error calling ismaster"); } /* Server Discovery and Monitoring Spec: if the server type changes from a * known type to Unknown its RTT is set to null. */ sd->round_trip_time_msec = -1; } /* *------------------------------------------------------------------------- * * Called during SDAM, from topology description's ismaster handler, or * when handshaking a connection in _mongoc_cluster_stream_for_server. * * If @ismaster_response is empty, @error must say why ismaster failed. * *------------------------------------------------------------------------- */ void mongoc_server_description_handle_ismaster (mongoc_server_description_t *sd, const bson_t *ismaster_response, int64_t rtt_msec, const bson_error_t *error /* IN */) { bson_iter_t iter; bson_iter_t child; 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) { _mongoc_server_description_set_error (sd, error); 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); } else if (strcmp ("lastWrite", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter) || !bson_iter_recurse (&iter, &child) || !bson_iter_find (&child, "lastWriteDate") || !BSON_ITER_HOLDS_DATE_TIME (&child)) { goto failure; } sd->last_write_date_ms = bson_iter_date_time (&child); } else if (strcmp ("idleWritePeriodMillis", bson_iter_key (&iter)) == 0) { sd->last_write_date_ms = bson_iter_as_int64 (&iter); #ifdef MONGOC_ENABLE_COMPRESSION } else if (strcmp ("compression", bson_iter_key (&iter)) == 0) { if (!BSON_ITER_HOLDS_ARRAY (&iter)) goto failure; bson_iter_array (&iter, &len, &bytes); bson_init_static (&sd->compressors, bytes, len); #endif } } 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; } if (!num_keys) { /* empty reply means ismaster failed */ _mongoc_server_description_set_error (sd, error); } mongoc_server_description_update_rtt (sd, rtt_msec); EXIT; failure: sd->type = MONGOC_SERVER_UNKNOWN; sd->round_trip_time_msec = -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; copy->opened = description->opened; memcpy (©->host, &description->host, sizeof (copy->host)); copy->round_trip_time_msec = -1; copy->connection_address = copy->host.host_and_port; bson_init (©->last_is_master); if (description->has_is_master) { /* calls mongoc_server_description_reset */ mongoc_server_description_handle_ismaster ( copy, &description->last_is_master, description->round_trip_time_msec, &description->error); } else { mongoc_server_description_reset (copy); } /* Preserve the error */ memcpy (©->error, &description->error, sizeof copy->error); return copy; } /* *------------------------------------------------------------------------- * * mongoc_server_description_filter_stale -- * * Estimate servers' staleness according to the Server Selection Spec. * Determines the number of eligible servers, and sets any servers that * are too stale to NULL in the descriptions set. * *------------------------------------------------------------------------- */ void mongoc_server_description_filter_stale (mongoc_server_description_t **sds, size_t sds_len, mongoc_server_description_t *primary, int64_t heartbeat_frequency_ms, const mongoc_read_prefs_t *read_prefs) { int64_t max_staleness_seconds; size_t i; int64_t heartbeat_frequency_usec; int64_t max_last_write_date_usec; int64_t staleness_usec; int64_t max_staleness_usec; if (!read_prefs) { /* NULL read_prefs is PRIMARY, no maxStalenessSeconds to filter by */ return; } max_staleness_seconds = mongoc_read_prefs_get_max_staleness_seconds (read_prefs); if (max_staleness_seconds == MONGOC_NO_MAX_STALENESS) { return; } BSON_ASSERT (max_staleness_seconds > 0); max_staleness_usec = max_staleness_seconds * 1000 * 1000; heartbeat_frequency_usec = heartbeat_frequency_ms * 1000; if (primary) { for (i = 0; i < sds_len; i++) { if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) { continue; } /* See max-staleness.rst for explanation of these formulae. */ staleness_usec = primary->last_write_date_ms * 1000 + (sds[i]->last_update_time_usec - primary->last_update_time_usec) - sds[i]->last_write_date_ms * 1000 + heartbeat_frequency_usec; if (staleness_usec > max_staleness_usec) { TRACE ("Rejected stale RSSecondary [%s]", sds[i]->host.host_and_port); sds[i] = NULL; } } } else { /* find max last_write_date */ max_last_write_date_usec = 0; for (i = 0; i < sds_len; i++) { if (sds[i] && sds[i]->type == MONGOC_SERVER_RS_SECONDARY) { max_last_write_date_usec = BSON_MAX ( max_last_write_date_usec, sds[i]->last_write_date_ms * 1000); } } /* use max last_write_date to estimate each secondary's staleness */ for (i = 0; i < sds_len; i++) { if (!sds[i] || sds[i]->type != MONGOC_SERVER_RS_SECONDARY) { continue; } staleness_usec = max_last_write_date_usec - sds[i]->last_write_date_ms * 1000 + heartbeat_frequency_usec; if (staleness_usec > max_staleness_usec) { TRACE ("Rejected stale RSSecondary [%s]", sds[i]->host.host_and_port); sds[i] = NULL; } } } } /* *------------------------------------------------------------------------- * * mongoc_server_description_filter_tags -- * * Given a set of server descriptions, set to NULL any that don't * match the the read preference's tag sets. * * https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#tag-set * *------------------------------------------------------------------------- */ void mongoc_server_description_filter_tags ( 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 tag_set_iter; bool *sd_matched = NULL; bool found; size_t i; if (!read_prefs) { /* NULL read_prefs is PRIMARY, no tags to filter by */ return; } rp_tags = mongoc_read_prefs_get_tags (read_prefs); if (bson_count_keys (rp_tags) == 0) { /* no tags to filter by */ return; } sd_matched = (bool *) bson_malloc0 (sizeof (bool) * description_len); bson_iter_init (&rp_tagset_iter, rp_tags); /* for each read preference tag set */ while (bson_iter_next (&rp_tagset_iter)) { found = false; for (i = 0; i < description_len; i++) { if (!descriptions[i]) { /* NULLed earlier in mongoc_topology_description_suitable_servers */ continue; } bson_iter_recurse (&rp_tagset_iter, &tag_set_iter); sd_matched[i] = _match_tag_set (descriptions[i], &tag_set_iter); if (sd_matched[i]) { found = true; } } if (found) { for (i = 0; i < description_len; i++) { if (!sd_matched[i] && descriptions[i]) { TRACE ("Rejected [%s] [%s], doesn't match tags", mongoc_server_description_type (descriptions[i]), descriptions[i]->host.host_and_port); descriptions[i] = NULL; } } goto CLEANUP; } } /* tried each */ for (i = 0; i < description_len; i++) { if (!sd_matched[i]) { TRACE ("Rejected [%s] [%s], reached end of tags array without match", mongoc_server_description_type (descriptions[i]), descriptions[i]->host.host_and_port); descriptions[i] = NULL; } } CLEANUP: bson_free (sd_matched); } /* *------------------------------------------------------------------------- * * _match_tag_set -- * * Check if a server's tags match one tag set, like * {'tag1': 'value1', 'tag2': 'value2'}. * *------------------------------------------------------------------------- */ static bool _match_tag_set (const mongoc_server_description_t *sd, bson_iter_t *tag_set_iter) { bson_iter_t sd_iter; uint32_t read_pref_tag_len; uint32_t sd_len; const char *read_pref_tag; const char *read_pref_val; const char *server_val; while (bson_iter_next (tag_set_iter)) { /* one {'tag': 'value'} pair from the read preference's tag set */ read_pref_tag = bson_iter_key (tag_set_iter); read_pref_val = bson_iter_utf8 (tag_set_iter, &read_pref_tag_len); if (bson_iter_init_find (&sd_iter, &sd->tags, read_pref_tag)) { /* The server has this tag - does it have the right value? */ server_val = bson_iter_utf8 (&sd_iter, &sd_len); if (sd_len != read_pref_tag_len || memcmp (read_pref_val, server_val, read_pref_tag_len)) { /* If the values don't match, no match */ return false; } } else { /* If the server description doesn't have that key, no match */ return false; } } return true; } #ifdef MONGOC_ENABLE_COMPRESSION /* *-------------------------------------------------------------------------- * * mongoc_server_description_compressor_id -- * * Get the compressor id if compression was negotiated. * * Returns: * The compressor ID, or 0 if none was negotiated. * *-------------------------------------------------------------------------- */ int32_t mongoc_server_description_compressor_id ( const mongoc_server_description_t *description) { int id; bson_iter_t iter; bson_iter_init (&iter, &description->compressors); while (bson_iter_next (&iter)) { id = mongoc_compressor_name_to_id (bson_iter_utf8 (&iter, NULL)); if (id != -1) { return id; } } return 0; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-server-description.h0000664000175000017500000000351013210321137025065 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-macros.h" #include "mongoc-read-prefs.h" #include "mongoc-host-list.h" BSON_BEGIN_DECLS typedef struct _mongoc_server_description_t mongoc_server_description_t; MONGOC_EXPORT (void) mongoc_server_description_destroy (mongoc_server_description_t *description); MONGOC_EXPORT (mongoc_server_description_t *) mongoc_server_description_new_copy ( const mongoc_server_description_t *description); MONGOC_EXPORT (uint32_t) mongoc_server_description_id (const mongoc_server_description_t *description); MONGOC_EXPORT (mongoc_host_list_t *) mongoc_server_description_host (const mongoc_server_description_t *description); MONGOC_EXPORT (int64_t) mongoc_server_description_round_trip_time ( const mongoc_server_description_t *description); MONGOC_EXPORT (const char *) mongoc_server_description_type (const mongoc_server_description_t *description); MONGOC_EXPORT (const bson_t *) mongoc_server_description_ismaster ( const mongoc_server_description_t *description); #ifdef MONGOC_ENABLE_COMPRESSION MONGOC_EXPORT (int32_t) mongoc_server_description_compressor_id ( const mongoc_server_description_t *description); #endif BSON_END_DECLS #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-server-stream-private.h0000664000175000017500000000335413210321137025513 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_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.3.4/src/libmongoc/src/mongoc/mongoc-server-stream.c0000664000175000017500000000565713210321137024046 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" #include "mongoc-util-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "server-stream" 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.3.4/src/libmongoc/src/mongoc/mongoc-set-private.h0000664000175000017500000000446313210321137023511 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_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_get_item_and_id (mongoc_set_t *set, int idx, uint32_t *id /* OUT */); 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.3.4/src/libmongoc/src/mongoc/mongoc-set.c0000664000175000017500000001120313210321137022022 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_get_item_and_id (mongoc_set_t *set, int idx, uint32_t *id /* OUT */) { BSON_ASSERT (set); BSON_ASSERT (id); BSON_ASSERT (idx < set->items_len); *id = set->items[idx].id; 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; /* prevent undefined behavior of memcpy(NULL) */ if (items_len == 0) { return; } 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.3.4/src/libmongoc/src/mongoc/mongoc-socket-private.h0000664000175000017500000000220413210321137024175 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; int pid; }; 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.3.4/src/libmongoc/src/mongoc/mongoc-socket.c0000664000175000017500000010725113210321137022530 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-private.h" #ifdef _WIN32 #include #endif #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "socket" #define OPERATION_EXPIRED(expire_at) \ ((expire_at >= 0) && (expire_at < (bson_get_monotonic_time ()))) /* either struct sockaddr or void, depending on platform */ typedef MONGOC_SOCKET_ARG2 mongoc_sockaddr_t; /* *-------------------------------------------------------------------------- * * _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 %s", sock->errno_, strerror (sock->errno_)); } /* *-------------------------------------------------------------------------- * * _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 _mongoc_socket_wait (mongoc_socket_t *sock, /* IN */ int events, /* IN */ int64_t expire_at) /* IN */ { #ifdef _WIN32 fd_set read_fds; fd_set write_fds; fd_set error_fds; struct timeval timeout_tv; #else struct pollfd pfd; #endif int ret; int timeout; int64_t now; ENTRY; BSON_ASSERT (sock); BSON_ASSERT (events); #ifdef _WIN32 FD_ZERO (&read_fds); FD_ZERO (&write_fds); FD_ZERO (&error_fds); if (events & POLLIN) { FD_SET (sock->sd, &read_fds); } if (events & POLLOUT) { FD_SET (sock->sd, &write_fds); } FD_SET (sock->sd, &error_fds); #else pfd.fd = sock->sd; pfd.events = events | POLLERR | POLLHUP; pfd.revents = 0; #endif 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 if (timeout == -1) { /* not WSAPoll: daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken */ ret = select (0 /*unused*/, &read_fds, &write_fds, &error_fds, NULL); } else { timeout_tv.tv_sec = timeout / 1000; timeout_tv.tv_usec = (timeout % 1000) * 1000; ret = select ( 0 /*unused*/, &read_fds, &write_fds, &error_fds, &timeout_tv); } if (ret == SOCKET_ERROR) { _mongoc_socket_capture_errno (sock); ret = -1; } else if (FD_ISSET (sock->sd, &error_fds)) { errno = WSAECONNRESET; ret = -1; } #else ret = poll (&pfd, 1, timeout); #endif if (ret > 0) { /* Something happened, so return that */ #ifdef _WIN32 return (FD_ISSET (sock->sd, &read_fds) || FD_ISSET (sock->sd, &write_fds)); #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) { _mongoc_socket_capture_errno (sock); RETURN (false); } else { continue; } } else { /* poll failed for some non-transient reason */ _mongoc_socket_capture_errno (sock); RETURN (false); } } else { /* ret == 0, poll timed out */ #ifdef _WIN32 sock->errno_ = timeout ? WSAETIMEDOUT : EAGAIN; #else sock->errno_ = timeout ? ETIMEDOUT : EAGAIN; #endif RETURN (false); } } } /* *-------------------------------------------------------------------------- * * mongoc_socket_poll -- * * A multi-socket poll helper. * * @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: * The number of sockets ready. * * Side effects: * None. * *-------------------------------------------------------------------------- */ ssize_t mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */ size_t nsds, /* IN */ int32_t timeout) /* IN */ { #ifdef _WIN32 fd_set read_fds; fd_set write_fds; fd_set error_fds; struct timeval timeout_tv; #else struct pollfd *pfds; #endif int ret; int i; ENTRY; BSON_ASSERT (sds); #ifdef _WIN32 FD_ZERO (&read_fds); FD_ZERO (&write_fds); FD_ZERO (&error_fds); for (i = 0; i < nsds; i++) { if (sds[i].events & POLLIN) { FD_SET (sds[i].socket->sd, &read_fds); } if (sds[i].events & POLLOUT) { FD_SET (sds[i].socket->sd, &write_fds); } FD_SET (sds[i].socket->sd, &error_fds); } timeout_tv.tv_sec = timeout / 1000; timeout_tv.tv_usec = (timeout % 1000) * 1000; /* not WSAPoll: daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken */ ret = select (0 /*unused*/, &read_fds, &write_fds, &error_fds, &timeout_tv); if (ret == SOCKET_ERROR) { errno = WSAGetLastError (); return -1; } for (i = 0; i < nsds; i++) { if (FD_ISSET (sds[i].socket->sd, &read_fds)) { sds[i].revents = POLLIN; } else if (FD_ISSET (sds[i].socket->sd, &write_fds)) { sds[i].revents = POLLOUT; } else if (FD_ISSET (sds[i].socket->sd, &error_fds)) { sds[i].revents = POLLHUP; } else { sds[i].revents = 0; } } #else pfds = (struct pollfd *) bson_malloc (sizeof (*pfds) * nsds); for (i = 0; i < nsds; i++) { pfds[i].fd = sds[i].socket->sd; pfds[i].events = sds[i].events | POLLERR | POLLHUP; pfds[i].revents = 0; } ret = poll (pfds, nsds, timeout); for (i = 0; i < nsds; i++) { sds[i].revents = pfds[i].revents; } bson_free (pfds); #endif return ret; } /* https://jira.mongodb.org/browse/CDRIVER-2176 */ #define MONGODB_KEEPALIVEINTVL 10 #define MONGODB_KEEPIDLE 300 #define MONGODB_KEEPALIVECNT 9 #ifdef _WIN32 static void _mongoc_socket_setkeepalive_windows (SOCKET sd) { BOOL optval = 1; struct tcp_keepalive keepalive; DWORD lpcbBytesReturned = 0; HKEY hKey; DWORD type; DWORD data; DWORD data_size = sizeof data; const char *reg_key = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"; keepalive.onoff = true; keepalive.keepalivetime = MONGODB_KEEPIDLE * 1000; keepalive.keepaliveinterval = MONGODB_KEEPALIVEINTVL * 1000; /* * Windows hardcodes probes to 10: * https://msdn.microsoft.com/en-us/library/windows/desktop/dd877220(v=vs.85).aspx * "On Windows Vista and later, the number of keep-alive probes (data * retransmissions) is set to 10 and cannot be changed." * * Note that win2k (and seeminly all versions thereafter) do not set the * registry value by default so there is no way to derive the default value * programmatically. It is however listed in the docs. A user can however * change the default value by setting the registry values. */ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, reg_key, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { /* https://technet.microsoft.com/en-us/library/cc957549.aspx */ DWORD default_keepalivetime = 7200000; /* 2 hours */ /* https://technet.microsoft.com/en-us/library/cc957548.aspx */ DWORD default_keepaliveinterval = 1000; /* 1 second */ if (RegQueryValueEx ( hKey, "KeepAliveTime", NULL, &type, (LPBYTE) &data, &data_size) == ERROR_SUCCESS) { if (type == REG_DWORD && data < keepalive.keepalivetime) { keepalive.keepalivetime = data; } } else if (default_keepalivetime < keepalive.keepalivetime) { keepalive.keepalivetime = default_keepalivetime; } if (RegQueryValueEx (hKey, "KeepAliveInterval", NULL, &type, (LPBYTE) &data, &data_size) == ERROR_SUCCESS) { if (type == REG_DWORD && data < keepalive.keepaliveinterval) { keepalive.keepaliveinterval = data; } } else if (default_keepaliveinterval < keepalive.keepaliveinterval) { keepalive.keepaliveinterval = default_keepaliveinterval; } RegCloseKey (hKey); } if (WSAIoctl (sd, SIO_KEEPALIVE_VALS, &keepalive, sizeof keepalive, NULL, 0, &lpcbBytesReturned, NULL, NULL) == SOCKET_ERROR) { TRACE ("Could not set keepalive values"); } else { TRACE ("KeepAlive values updated"); TRACE ("KeepAliveTime: %d", keepalive.keepalivetime); TRACE ("KeepAliveInterval: %d", keepalive.keepaliveinterval); } } #else #ifdef MONGOC_TRACE static const char * _mongoc_socket_sockopt_value_to_name (int value) { switch (value) { #ifdef TCP_KEEPIDLE case TCP_KEEPIDLE: return "TCP_KEEPIDLE"; #endif #ifdef TCP_KEEPALIVE case TCP_KEEPALIVE: return "TCP_KEEPALIVE"; #endif #ifdef TCP_KEEPINTVL case TCP_KEEPINTVL: return "TCP_KEEPINTVL"; #endif #ifdef TCP_KEEPCNT case TCP_KEEPCNT: return "TCP_KEEPCNT"; #endif default: MONGOC_WARNING ("Don't know what socketopt %d is", value); return "Unknown option name"; } } #endif static void _mongoc_socket_set_sockopt_if_less (int sd, int name, int value) { int optval = 1; mongoc_socklen_t optlen; optlen = sizeof optval; if (getsockopt (sd, IPPROTO_TCP, name, (char *) &optval, &optlen)) { TRACE ("Getting '%s' failed, errno: %d", _mongoc_socket_sockopt_value_to_name (name), errno); } else { TRACE ("'%s' is %d, target value is %d", _mongoc_socket_sockopt_value_to_name (name), optval, value); if (optval > value) { optval = value; if (setsockopt ( sd, IPPROTO_TCP, name, (char *) &optval, sizeof optval)) { TRACE ("Setting '%s' failed, errno: %d", _mongoc_socket_sockopt_value_to_name (name), errno); } else { TRACE ("'%s' value changed to %d", _mongoc_socket_sockopt_value_to_name (name), optval); } } } } static void _mongoc_socket_setkeepalive_nix (int sd) { #if defined(TCP_KEEPIDLE) _mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPIDLE, MONGODB_KEEPIDLE); #elif defined(TCP_KEEPALIVE) _mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPALIVE, MONGODB_KEEPIDLE); #else TRACE ("%s", "Neither TCP_KEEPIDLE nor TCP_KEEPALIVE available"); #endif #ifdef TCP_KEEPINTVL _mongoc_socket_set_sockopt_if_less ( sd, TCP_KEEPINTVL, MONGODB_KEEPALIVEINTVL); #else TRACE ("%s", "TCP_KEEPINTVL not available"); #endif #ifdef TCP_KEEPCNT _mongoc_socket_set_sockopt_if_less (sd, TCP_KEEPCNT, MONGODB_KEEPALIVECNT); #else TRACE ("%s", "TCP_KEEPCNT not available"); #endif } #endif static void #ifdef _WIN32 _mongoc_socket_setkeepalive (SOCKET sd) /* IN */ #else _mongoc_socket_setkeepalive (int sd) /* IN */ #endif { #ifdef SO_KEEPALIVE int optval = 1; ENTRY; #ifdef SO_KEEPALIVE if (!setsockopt ( sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof optval)) { TRACE ("%s", "Setting SO_KEEPALIVE"); #ifdef _WIN32 _mongoc_socket_setkeepalive_windows (sd); #else _mongoc_socket_setkeepalive_nix (sd); #endif } else { TRACE ("%s", "Failed setting SO_KEEPALIVE"); } #else TRACE ("%s", "SO_KEEPALIVE not available"); #endif EXIT; #endif } 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_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 = {0}; mongoc_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, (mongoc_sockaddr_t *) &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, 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 */ mongoc_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); } int mongoc_socket_close (mongoc_socket_t *sock) /* IN */ { bool owned; ENTRY; BSON_ASSERT (sock); owned = (sock->pid == (int) getpid ()); #ifdef _WIN32 if (sock->sd != INVALID_SOCKET) { if (owned) { 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) { if (owned) { 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 */ mongoc_socklen_t addrlen, /* IN */ int64_t expire_at) /* IN */ { bool try_again = false; bool failed = false; int ret; int optval; /* getsockopt parameter types vary, we check in CheckCompiler.m4 */ mongoc_socklen_t optlen = (mongoc_socklen_t) 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, 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 and store the current process id on it. * * Free the result with 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) { if (!_mongoc_socket_setnodelay (sd)) { MONGOC_WARNING ("Failed to enable TCP_NODELAY."); } _mongoc_socket_setkeepalive (sd); } sock = (mongoc_socket_t *) bson_malloc0 (sizeof *sock); sock->sd = sd; sock->domain = domain; sock->pid = (int) getpid (); 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, 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 */ mongoc_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].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, POLLOUT, expire_at)) { GOTO (CLEANUP); } } CLEANUP: bson_free (iov); RETURN (ret); } int mongoc_socket_getsockname (mongoc_socket_t *sock, /* IN */ struct sockaddr *addr, /* OUT */ mongoc_socklen_t *addrlen) /* INOUT */ { int ret; ENTRY; BSON_ASSERT (sock); ret = getsockname (sock->sd, (mongoc_sockaddr_t *) addr, addrlen); _mongoc_socket_capture_errno (sock); RETURN (ret); } char * mongoc_socket_getnameinfo (mongoc_socket_t *sock) /* IN */ { /* getpeername parameter types vary, we check in CheckCompiler.m4 */ mongoc_sockaddr_t addr; mongoc_socklen_t len = (mongoc_socklen_t) 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, 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.3.4/src/libmongoc/src/mongoc/mongoc-socket.h0000664000175000017500000000676713210321137022547 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 #include "mongoc-macros.h" #include "mongoc-config.h" #ifdef _WIN32 #include #include #else #include #include #include #include #include #include #include #include #include #endif #include "mongoc-iovec.h" BSON_BEGIN_DECLS typedef MONGOC_SOCKET_ARG3 mongoc_socklen_t; typedef struct _mongoc_socket_t mongoc_socket_t; typedef struct { mongoc_socket_t *socket; int events; int revents; } mongoc_socket_poll_t; MONGOC_EXPORT (mongoc_socket_t *) mongoc_socket_accept (mongoc_socket_t *sock, int64_t expire_at); MONGOC_EXPORT (int) mongoc_socket_bind (mongoc_socket_t *sock, const struct sockaddr *addr, mongoc_socklen_t addrlen); MONGOC_EXPORT (int) mongoc_socket_close (mongoc_socket_t *socket); MONGOC_EXPORT (int) mongoc_socket_connect (mongoc_socket_t *sock, const struct sockaddr *addr, mongoc_socklen_t addrlen, int64_t expire_at); MONGOC_EXPORT (char *) mongoc_socket_getnameinfo (mongoc_socket_t *sock); MONGOC_EXPORT (void) mongoc_socket_destroy (mongoc_socket_t *sock); MONGOC_EXPORT (int) mongoc_socket_errno (mongoc_socket_t *sock); MONGOC_EXPORT (int) mongoc_socket_getsockname (mongoc_socket_t *sock, struct sockaddr *addr, mongoc_socklen_t *addrlen); MONGOC_EXPORT (int) mongoc_socket_listen (mongoc_socket_t *sock, unsigned int backlog); MONGOC_EXPORT (mongoc_socket_t *) mongoc_socket_new (int domain, int type, int protocol); MONGOC_EXPORT (ssize_t) mongoc_socket_recv (mongoc_socket_t *sock, void *buf, size_t buflen, int flags, int64_t expire_at); MONGOC_EXPORT (int) mongoc_socket_setsockopt (mongoc_socket_t *sock, int level, int optname, const void *optval, mongoc_socklen_t optlen); MONGOC_EXPORT (ssize_t) mongoc_socket_send (mongoc_socket_t *sock, const void *buf, size_t buflen, int64_t expire_at); MONGOC_EXPORT (ssize_t) mongoc_socket_sendv (mongoc_socket_t *sock, mongoc_iovec_t *iov, size_t iovcnt, int64_t expire_at); MONGOC_EXPORT (bool) mongoc_socket_check_closed (mongoc_socket_t *sock); MONGOC_EXPORT (void) mongoc_socket_inet_ntop (struct addrinfo *rp, char *buf, size_t buflen); MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-ssl-private.h0000664000175000017500000000225613210321137023515 0ustar jmikolajmikola/* * Copyright 2016 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_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-uri-private.h" BSON_BEGIN_DECLS char * mongoc_ssl_extract_subject (const char *filename, const char *passphrase); void _mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt, mongoc_uri_t *uri); void _mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src, mongoc_ssl_opt_t *dst); void _mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt); BSON_END_DECLS #endif /* MONGOC_SSL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-ssl.c0000664000175000017500000001011313210321137022027 0ustar jmikolajmikola/* * Copyright 2016 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-ssl.h" #include "mongoc-ssl-private.h" #include "mongoc-log.h" #include "mongoc-uri.h" #if defined(MONGOC_ENABLE_SSL_OPENSSL) #include "mongoc-openssl-private.h" #elif defined(MONGOC_ENABLE_SSL_LIBRESSL) #include "mongoc-libressl-private.h" #elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) #include "mongoc-secure-transport-private.h" #elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) #include "mongoc-secure-channel-private.h" #endif /* 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, }; const mongoc_ssl_opt_t * mongoc_ssl_opt_get_default (void) { return &gMongocSslOptDefault; } char * mongoc_ssl_extract_subject (const char *filename, const char *passphrase) { char *retval; if (!filename) { MONGOC_ERROR ("No filename provided to extract subject from"); return NULL; } #ifdef _WIN32 if (_access (filename, 0) != 0) { #else if (access (filename, R_OK) != 0) { #endif MONGOC_ERROR ("Can't extract subject from unreadable file: '%s'", filename); return NULL; } #if defined(MONGOC_ENABLE_SSL_OPENSSL) retval = _mongoc_openssl_extract_subject (filename, passphrase); #elif defined(MONGOC_ENABLE_SSL_LIBRESSL) MONGOC_WARNING ( "libtls doesn't support automatically extracting subject from " "certificate to use with authentication"); retval = NULL; #elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) retval = _mongoc_secure_transport_extract_subject (filename, passphrase); #elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) retval = _mongoc_secure_channel_extract_subject (filename, passphrase); #endif if (!retval) { MONGOC_ERROR ("Can't extract subject from file '%s'", filename); } return retval; } void _mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t *ssl_opt, mongoc_uri_t *uri) { ssl_opt->pem_file = mongoc_uri_get_option_as_utf8 ( uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE, NULL); ssl_opt->pem_pwd = mongoc_uri_get_option_as_utf8 ( uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD, NULL); ssl_opt->ca_file = mongoc_uri_get_option_as_utf8 ( uri, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE, NULL); ssl_opt->weak_cert_validation = mongoc_uri_get_option_as_bool ( uri, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES, false); ssl_opt->allow_invalid_hostname = mongoc_uri_get_option_as_bool ( uri, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES, false); } void _mongoc_ssl_opts_copy_to (const mongoc_ssl_opt_t *src, mongoc_ssl_opt_t *dst) { BSON_ASSERT (src); BSON_ASSERT (dst); dst->pem_file = bson_strdup (src->pem_file); dst->pem_pwd = bson_strdup (src->pem_pwd); dst->ca_file = bson_strdup (src->ca_file); dst->ca_dir = bson_strdup (src->ca_dir); dst->crl_file = bson_strdup (src->crl_file); dst->weak_cert_validation = src->weak_cert_validation; dst->allow_invalid_hostname = src->allow_invalid_hostname; } void _mongoc_ssl_opts_cleanup (mongoc_ssl_opt_t *opt) { bson_free ((char *) opt->pem_file); bson_free ((char *) opt->pem_pwd); bson_free ((char *) opt->ca_file); bson_free ((char *) opt->ca_dir); bson_free ((char *) opt->crl_file); } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-ssl.h0000664000175000017500000000234213210321137022041 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 #include "mongoc-macros.h" 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; bool allow_invalid_hostname; void *padding[7]; }; MONGOC_EXPORT (const mongoc_ssl_opt_t *) mongoc_ssl_opt_get_default (void) BSON_GNUC_CONST; BSON_END_DECLS #endif /* MONGOC_SSL_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-sspi-private.h0000664000175000017500000000465713210321137023701 0ustar jmikolajmikola/* * Copyright 2017 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_SSPI_PRIVATE_H #define MONGOC_SSPI_PRIVATE_H #if !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #include BSON_BEGIN_DECLS #define SECURITY_WIN32 1 /* Required for SSPI */ #include #include #include #include #define MONGOC_SSPI_AUTH_GSS_ERROR -1 #define MONGOC_SSPI_AUTH_GSS_COMPLETE 1 #define MONGOC_SSPI_AUTH_GSS_CONTINUE 0 typedef struct { CredHandle cred; CtxtHandle ctx; WCHAR *spn; SEC_CHAR *response; SEC_CHAR *username; ULONG flags; UCHAR haveCred; UCHAR haveCtx; INT qop; } mongoc_sspi_client_state_t; void _mongoc_sspi_set_gsserror (DWORD errCode, const SEC_CHAR *msg); void _mongoc_sspi_destroy_sspi_client_state (mongoc_sspi_client_state_t *state); int _mongoc_sspi_auth_sspi_client_init (WCHAR *service, ULONG flags, WCHAR *user, ULONG ulen, WCHAR *domain, ULONG dlen, WCHAR *password, ULONG plen, mongoc_sspi_client_state_t *state); int _mongoc_sspi_auth_sspi_client_step (mongoc_sspi_client_state_t *state, SEC_CHAR *challenge); int _mongoc_sspi_auth_sspi_client_unwrap (mongoc_sspi_client_state_t *state, SEC_CHAR *challenge); int _mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, SEC_CHAR *data, SEC_CHAR *user, ULONG ulen, INT protect); BSON_END_DECLS #endif /* MONGOC_SSPI_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-sspi.c0000664000175000017500000004022413210321137022212 0ustar jmikolajmikola/* * Copyright 2017 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. * * This file originates from https://github.com/mongodb-labs/winkerberos */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SASL_SSPI /* mingw doesn't define this */ #ifndef CRYPT_STRING_NOCRLF #define CRYPT_STRING_NOCRLF 0x40000000 #endif #include "mongoc-util-private.h" #include "mongoc-sspi-private.h" void _mongoc_sspi_destroy_sspi_client_state (mongoc_sspi_client_state_t *state) { if (state->haveCtx) { DeleteSecurityContext (&state->ctx); state->haveCtx = 0; } if (state->haveCred) { FreeCredentialsHandle (&state->cred); state->haveCred = 0; } if (state->spn != NULL) { free (state->spn); state->spn = NULL; } if (state->response != NULL) { free (state->response); state->response = NULL; } if (state->username != NULL) { free (state->username); state->username = NULL; } } void _mongoc_sspi_set_gsserror (DWORD errCode, const SEC_CHAR *msg) { SEC_CHAR *err; DWORD status; DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; status = FormatMessageA (flags, NULL, errCode, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &err, 0, NULL); if (status) { MONGOC_ERROR ("SSPI: %s: %s", msg, err); LocalFree (err); } else { MONGOC_ERROR ("SSPI: %s", msg); } } static SEC_CHAR * _mongoc_sspi_base64_encode (const SEC_CHAR *value, DWORD vlen) { SEC_CHAR *out = NULL; DWORD len; /* Get the correct size for the out buffer. */ if (CryptBinaryToStringA ((BYTE *) value, vlen, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &len)) { out = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * len); if (out) { /* Encode to the out buffer. */ if (CryptBinaryToStringA ((BYTE *) value, vlen, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, out, &len)) { return out; } else { free (out); } } } MONGOC_ERROR ("%s", "CryptBinaryToString failed."); return NULL; } static SEC_CHAR * _mongoc_sspi_base64_decode (const SEC_CHAR *value, DWORD *rlen) { SEC_CHAR *out = NULL; /* Get the correct size for the out buffer. */ if (CryptStringToBinaryA ( value, 0, CRYPT_STRING_BASE64, NULL, rlen, NULL, NULL)) { out = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * *rlen); if (out) { /* Decode to the out buffer. */ if (CryptStringToBinaryA (value, 0, CRYPT_STRING_BASE64, (BYTE *) out, rlen, NULL, NULL)) { return out; } else { free (out); } } } MONGOC_ERROR ("%s", "CryptStringToBinary failed."); return NULL; } static CHAR * _mongoc_sspi_wide_to_utf8 (WCHAR *value) { CHAR *out; int len = WideCharToMultiByte (CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL); if (len) { out = (CHAR *) malloc (sizeof (CHAR) * len); if (WideCharToMultiByte (CP_UTF8, 0, value, -1, out, len, NULL, NULL)) { return out; } else { free (out); } } _mongoc_sspi_set_gsserror (GetLastError (), "WideCharToMultiByte"); return NULL; } int _mongoc_sspi_auth_sspi_client_init (WCHAR *service, ULONG flags, WCHAR *user, ULONG ulen, WCHAR *domain, ULONG dlen, WCHAR *password, ULONG plen, mongoc_sspi_client_state_t *state) { SECURITY_STATUS status; SEC_WINNT_AUTH_IDENTITY_W authIdentity; TimeStamp ignored; state->response = NULL; state->username = NULL; state->qop = SECQOP_WRAP_NO_ENCRYPT; state->flags = flags; state->haveCred = 0; state->haveCtx = 0; state->spn = _wcsdup (service); if (state->spn == NULL) { return MONGOC_SSPI_AUTH_GSS_ERROR; } /* Convert RFC-2078 format to SPN */ if (!wcschr (state->spn, L'/')) { WCHAR *ptr = wcschr (state->spn, L'@'); if (ptr) { *ptr = L'/'; } } if (user) { authIdentity.User = user; authIdentity.UserLength = ulen; authIdentity.Domain = domain; authIdentity.DomainLength = dlen; authIdentity.Password = password; authIdentity.PasswordLength = plen; authIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; } /* Note that the first paramater, pszPrincipal, appears to be * completely ignored in the Kerberos SSP. For more details see * https://github.com/mongodb-labs/winkerberos/issues/11. * */ status = AcquireCredentialsHandleW (/* Principal */ NULL, /* Security package name */ L"kerberos", /* Credentials Use */ SECPKG_CRED_OUTBOUND, /* LogonID (We don't use this) */ NULL, /* AuthData */ user ? &authIdentity : NULL, /* Always NULL */ NULL, /* Always NULL */ NULL, /* CredHandle */ &state->cred, /* Expiry (Required but unused by us) */ &ignored); if (status != SEC_E_OK) { _mongoc_sspi_set_gsserror (status, "AcquireCredentialsHandle"); return MONGOC_SSPI_AUTH_GSS_ERROR; } state->haveCred = 1; return MONGOC_SSPI_AUTH_GSS_COMPLETE; } int _mongoc_sspi_auth_sspi_client_step (mongoc_sspi_client_state_t *state, SEC_CHAR *challenge) { SecBufferDesc inbuf; SecBuffer inBufs[1]; SecBufferDesc outbuf; SecBuffer outBufs[1]; ULONG ignored; SECURITY_STATUS status = MONGOC_SSPI_AUTH_GSS_CONTINUE; DWORD len; if (state->response != NULL) { free (state->response); state->response = NULL; } inbuf.ulVersion = SECBUFFER_VERSION; inbuf.cBuffers = 1; inbuf.pBuffers = inBufs; inBufs[0].pvBuffer = NULL; inBufs[0].cbBuffer = 0; inBufs[0].BufferType = SECBUFFER_TOKEN; if (state->haveCtx) { inBufs[0].pvBuffer = _mongoc_sspi_base64_decode (challenge, &len); if (!inBufs[0].pvBuffer) { return MONGOC_SSPI_AUTH_GSS_ERROR; } inBufs[0].cbBuffer = len; } outbuf.ulVersion = SECBUFFER_VERSION; outbuf.cBuffers = 1; outbuf.pBuffers = outBufs; outBufs[0].pvBuffer = NULL; outBufs[0].cbBuffer = 0; outBufs[0].BufferType = SECBUFFER_TOKEN; status = InitializeSecurityContextW (/* CredHandle */ &state->cred, /* CtxtHandle (NULL on first call) */ state->haveCtx ? &state->ctx : NULL, /* Service Principal Name */ state->spn, /* Flags */ ISC_REQ_ALLOCATE_MEMORY | state->flags, /* Always 0 */ 0, /* Target data representation */ SECURITY_NETWORK_DREP, /* Challenge (NULL on first call) */ state->haveCtx ? &inbuf : NULL, /* Always 0 */ 0, /* CtxtHandle (Set on first call) */ &state->ctx, /* Output */ &outbuf, /* Context attributes */ &ignored, /* Expiry (We don't use this) */ NULL); if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { _mongoc_sspi_set_gsserror (status, "InitializeSecurityContext"); status = MONGOC_SSPI_AUTH_GSS_ERROR; goto done; } state->haveCtx = 1; if (outBufs[0].cbBuffer) { state->response = _mongoc_sspi_base64_encode (outBufs[0].pvBuffer, outBufs[0].cbBuffer); if (!state->response) { status = MONGOC_SSPI_AUTH_GSS_ERROR; goto done; } } if (status == SEC_E_OK) { /* Get authenticated username. */ SecPkgContext_NamesW names; status = QueryContextAttributesW (&state->ctx, SECPKG_ATTR_NAMES, &names); if (status != SEC_E_OK) { _mongoc_sspi_set_gsserror (status, "QueryContextAttributesW"); status = MONGOC_SSPI_AUTH_GSS_ERROR; goto done; } state->username = _mongoc_sspi_wide_to_utf8 (names.sUserName); if (state->username == NULL) { FreeContextBuffer (names.sUserName); status = MONGOC_SSPI_AUTH_GSS_ERROR; goto done; } FreeContextBuffer (names.sUserName); status = MONGOC_SSPI_AUTH_GSS_COMPLETE; } else { status = MONGOC_SSPI_AUTH_GSS_CONTINUE; } done: if (inBufs[0].pvBuffer) { free (inBufs[0].pvBuffer); } if (outBufs[0].pvBuffer) { FreeContextBuffer (outBufs[0].pvBuffer); } return status; } int _mongoc_sspi_auth_sspi_client_unwrap (mongoc_sspi_client_state_t *state, SEC_CHAR *challenge) { SECURITY_STATUS status; DWORD len; SecBuffer wrapBufs[2]; SecBufferDesc wrapBufDesc; wrapBufDesc.ulVersion = SECBUFFER_VERSION; wrapBufDesc.cBuffers = 2; wrapBufDesc.pBuffers = wrapBufs; if (state->response != NULL) { free (state->response); state->response = NULL; state->qop = SECQOP_WRAP_NO_ENCRYPT; } if (!state->haveCtx) { return MONGOC_SSPI_AUTH_GSS_ERROR; } wrapBufs[0].pvBuffer = _mongoc_sspi_base64_decode (challenge, &len); if (!wrapBufs[0].pvBuffer) { return MONGOC_SSPI_AUTH_GSS_ERROR; } wrapBufs[0].cbBuffer = len; wrapBufs[0].BufferType = SECBUFFER_STREAM; wrapBufs[1].pvBuffer = NULL; wrapBufs[1].cbBuffer = 0; wrapBufs[1].BufferType = SECBUFFER_DATA; status = DecryptMessage (&state->ctx, &wrapBufDesc, 0, &state->qop); if (status == SEC_E_OK) { status = MONGOC_SSPI_AUTH_GSS_COMPLETE; } else { _mongoc_sspi_set_gsserror (status, "DecryptMessage"); status = MONGOC_SSPI_AUTH_GSS_ERROR; goto done; } if (wrapBufs[1].cbBuffer) { state->response = _mongoc_sspi_base64_encode (wrapBufs[1].pvBuffer, wrapBufs[1].cbBuffer); if (!state->response) { status = MONGOC_SSPI_AUTH_GSS_ERROR; } } done: if (wrapBufs[0].pvBuffer) { free (wrapBufs[0].pvBuffer); } return status; } int _mongoc_sspi_auth_sspi_client_wrap (mongoc_sspi_client_state_t *state, SEC_CHAR *data, SEC_CHAR *user, ULONG ulen, int protect) { SECURITY_STATUS status; SecPkgContext_Sizes sizes; SecBuffer wrapBufs[3]; SecBufferDesc wrapBufDesc; SEC_CHAR *decodedData = NULL; SEC_CHAR *inbuf; SIZE_T inbufSize; SEC_CHAR *outbuf; DWORD outbufSize; SEC_CHAR *plaintextMessage; ULONG plaintextMessageSize; if (state->response != NULL) { free (state->response); state->response = NULL; } if (!state->haveCtx) { return MONGOC_SSPI_AUTH_GSS_ERROR; } status = QueryContextAttributes (&state->ctx, SECPKG_ATTR_SIZES, &sizes); if (status != SEC_E_OK) { _mongoc_sspi_set_gsserror (status, "QueryContextAttributes"); return MONGOC_SSPI_AUTH_GSS_ERROR; } if (user) { /* Length of user + 4 bytes for security layer (see below). */ plaintextMessageSize = ulen + 4; } else { decodedData = _mongoc_sspi_base64_decode (data, &plaintextMessageSize); if (!decodedData) { return MONGOC_SSPI_AUTH_GSS_ERROR; } } inbufSize = sizes.cbSecurityTrailer + plaintextMessageSize + sizes.cbBlockSize; inbuf = (SEC_CHAR *) malloc (inbufSize); if (inbuf == NULL) { free (decodedData); return MONGOC_SSPI_AUTH_GSS_ERROR; } plaintextMessage = inbuf + sizes.cbSecurityTrailer; if (user) { /* Authenticate the provided user. Unlike pykerberos, we don't * need any information from "data" to do that. * */ plaintextMessage[0] = 1; /* No security layer */ plaintextMessage[1] = 0; plaintextMessage[2] = 0; plaintextMessage[3] = 0; memcpy_s (plaintextMessage + 4, inbufSize - sizes.cbSecurityTrailer - 4, user, strlen (user)); } else { /* No user provided. Just rewrap data. */ memcpy_s (plaintextMessage, inbufSize - sizes.cbSecurityTrailer, decodedData, plaintextMessageSize); free (decodedData); } wrapBufDesc.cBuffers = 3; wrapBufDesc.pBuffers = wrapBufs; wrapBufDesc.ulVersion = SECBUFFER_VERSION; wrapBufs[0].cbBuffer = sizes.cbSecurityTrailer; wrapBufs[0].BufferType = SECBUFFER_TOKEN; wrapBufs[0].pvBuffer = inbuf; wrapBufs[1].cbBuffer = (ULONG) plaintextMessageSize; wrapBufs[1].BufferType = SECBUFFER_DATA; wrapBufs[1].pvBuffer = inbuf + sizes.cbSecurityTrailer; wrapBufs[2].cbBuffer = sizes.cbBlockSize; wrapBufs[2].BufferType = SECBUFFER_PADDING; wrapBufs[2].pvBuffer = inbuf + (sizes.cbSecurityTrailer + plaintextMessageSize); status = EncryptMessage ( &state->ctx, protect ? 0 : SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0); if (status != SEC_E_OK) { free (inbuf); _mongoc_sspi_set_gsserror (status, "EncryptMessage"); return MONGOC_SSPI_AUTH_GSS_ERROR; } outbufSize = wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer; outbuf = (SEC_CHAR *) malloc (sizeof (SEC_CHAR) * outbufSize); memcpy_s (outbuf, outbufSize, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer); memcpy_s (outbuf + wrapBufs[0].cbBuffer, outbufSize - wrapBufs[0].cbBuffer, wrapBufs[1].pvBuffer, wrapBufs[1].cbBuffer); memcpy_s (outbuf + wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer, outbufSize - wrapBufs[0].cbBuffer - wrapBufs[1].cbBuffer, wrapBufs[2].pvBuffer, wrapBufs[2].cbBuffer); state->response = _mongoc_sspi_base64_encode (outbuf, outbufSize); if (!state->response) { status = MONGOC_SSPI_AUTH_GSS_ERROR; } else { status = MONGOC_SSPI_AUTH_GSS_COMPLETE; } free (inbuf); free (outbuf); return status; } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-buffered.c0000664000175000017500000002221013210321137024302 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-private.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 ("%s", 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); } static bool _mongoc_stream_buffered_timed_out (mongoc_stream_t *stream) /* IN */ { mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *) stream; BSON_ASSERT (stream); return mongoc_stream_timed_out (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->stream.timed_out = _mongoc_stream_buffered_timed_out; 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.3.4/src/libmongoc/src/mongoc/mongoc-stream-buffered.h0000664000175000017500000000202613210321137024312 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-macros.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-stream-file.c0000664000175000017500000001164013210321137023444 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-private.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.3.4/src/libmongoc/src/mongoc/mongoc-stream-file.h0000664000175000017500000000227713210321137023457 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-macros.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef struct _mongoc_stream_file_t mongoc_stream_file_t; MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_file_new (int fd); MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_file_new_for_path (const char *path, int flags, int mode); MONGOC_EXPORT (int) mongoc_stream_file_get_fd (mongoc_stream_file_t *stream); BSON_END_DECLS #endif /* MONGOC_STREAM_FILE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c0000664000175000017500000001001213210321137023773 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-private.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); /* timeout_msec is unused by mongoc_gridfs_file_readv */ ret = mongoc_gridfs_file_readv (file->file, iov, iovcnt, min_bytes, 0); 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); /* timeout_msec is unused by mongoc_gridfs_file_writev */ ret = mongoc_gridfs_file_writev (file->file, iov, iovcnt, 0); 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.3.4/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h0000664000175000017500000000202213210321137024002 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-macros.h" #include "mongoc-gridfs.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_gridfs_new (mongoc_gridfs_file_t *file); BSON_END_DECLS #endif /* MONGOC_STREAM_GRIDFS_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-private.h0000664000175000017500000000252213210321137024203 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_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.3.4/src/libmongoc/src/mongoc/mongoc-stream-socket.c0000664000175000017500000001626113210321137024021 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-private.h" #include "mongoc-socket-private.h" #include "mongoc-errno-private.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, mongoc_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); } static bool _mongoc_stream_socket_timed_out (mongoc_stream_t *stream) /* IN */ { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; ENTRY; BSON_ASSERT (ss); BSON_ASSERT (ss->sock); RETURN (MONGOC_ERRNO_IS_TIMEDOUT (ss->sock->errno_)); } /* *-------------------------------------------------------------------------- * * 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.timed_out = _mongoc_stream_socket_timed_out; stream->vtable.poll = _mongoc_stream_socket_poll; stream->sock = sock; return (mongoc_stream_t *) stream; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-socket.h0000664000175000017500000000224213210321137024020 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-macros.h" #include "mongoc-socket.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef struct _mongoc_stream_socket_t mongoc_stream_socket_t; MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_socket_new (mongoc_socket_t *socket); MONGOC_EXPORT (mongoc_socket_t *) mongoc_stream_socket_get_socket (mongoc_stream_socket_t *stream); BSON_END_DECLS #endif /* MONGOC_STREAM_SOCKET_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl-private.h0000664000175000017500000000224313210321137026620 0ustar jmikolajmikola/* * Copyright 2016 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_LIBRESSL_PRIVATE_H #define MONGOC_STREAM_TLS_LIBRESSL_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_LIBRESSL #include #include BSON_BEGIN_DECLS /** * mongoc_stream_tls_libressl_t: * * Private storage for LibreSSL Streams */ typedef struct { struct tls *ctx; struct tls_config *config; } mongoc_stream_tls_libressl_t; BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_LIBRESSL */ #endif /* MONGOC_STREAM_TLS_LIBRESSL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.c0000664000175000017500000003626013210321137025151 0ustar jmikolajmikola/* * Copyright 2016 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_LIBRESSL #include #include "mongoc-trace-private.h" #include "mongoc-log.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-tls-private.h" #include "mongoc-stream-private.h" #include "mongoc-stream-tls-libressl-private.h" #include "mongoc-libressl-private.h" #include "mongoc-ssl.h" #include "mongoc-error.h" #include "mongoc-counters-private.h" #include "mongoc-stream-socket.h" #include "mongoc-socket-private.h" #include #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-tls-libressl" static void _mongoc_stream_tls_libressl_destroy (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; ENTRY; BSON_ASSERT (libressl); tls_close (libressl->ctx); tls_free (libressl->ctx); tls_config_free (libressl->config); mongoc_stream_destroy (tls->base_stream); bson_free (libressl); bson_free (stream); mongoc_counter_streams_active_dec (); mongoc_counter_streams_disposed_inc (); EXIT; } static void _mongoc_stream_tls_libressl_failed (mongoc_stream_t *stream) { ENTRY; _mongoc_stream_tls_libressl_destroy (stream); EXIT; } static int _mongoc_stream_tls_libressl_close (mongoc_stream_t *stream) { int ret = 0; mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; ENTRY; BSON_ASSERT (libressl); ret = mongoc_stream_close (tls->base_stream); RETURN (ret); } static int _mongoc_stream_tls_libressl_flush (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; ENTRY; BSON_ASSERT (libressl); RETURN (0); } static ssize_t _mongoc_stream_tls_libressl_write (mongoc_stream_t *stream, char *buf, size_t buf_len) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; mongoc_stream_poll_t poller; ssize_t total_write = 0; ssize_t ret; int64_t now; int64_t expire = 0; ENTRY; BSON_ASSERT (libressl); if (tls->timeout_msec >= 0) { expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL); } do { poller.stream = stream; poller.revents = 0; poller.events = POLLOUT; ret = tls_write (libressl->ctx, buf, buf_len); if (ret == TLS_WANT_POLLIN) { poller.events = POLLIN; mongoc_stream_poll (&poller, 1, tls->timeout_msec); } else if (ret == TLS_WANT_POLLOUT) { poller.events = POLLOUT; mongoc_stream_poll (&poller, 1, tls->timeout_msec); } else if (ret < 0) { RETURN (total_write); } else { buf += ret; buf_len -= ret; total_write += ret; } if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { if (ret == 0) { mongoc_counter_streams_timeout_inc (); break; } tls->timeout_msec = 0; } else { tls->timeout_msec = (expire - now) / 1000L; } } } while (buf_len > 0); RETURN (total_write); } /* This is copypasta from _mongoc_stream_tls_openssl_writev */ #define MONGOC_STREAM_TLS_BUFFER_SIZE 4096 static ssize_t _mongoc_stream_tls_libressl_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; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; 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 (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (libressl); 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_libressl_write ( stream, to_write, to_write_len); if (child_ret < 0) { 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_libressl_write ( stream, 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); } TRACE ("Returning %zu", ret); RETURN (ret); } /* This function is copypasta of _mongoc_stream_tls_openssl_readv */ static ssize_t _mongoc_stream_tls_libressl_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; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; ssize_t ret = 0; ssize_t read_ret; size_t i; size_t iov_pos = 0; int64_t now; int64_t expire = 0; mongoc_stream_poll_t poller; BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (libressl); ENTRY; 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) { poller.stream = stream; poller.revents = 0; poller.events = POLLIN; read_ret = tls_read (libressl->ctx, (char *) iov[i].iov_base + iov_pos, (int) (iov[i].iov_len - iov_pos)); if (read_ret == TLS_WANT_POLLIN) { poller.events = POLLIN; mongoc_stream_poll (&poller, 1, tls->timeout_msec); } else if (read_ret == TLS_WANT_POLLOUT) { poller.events = POLLOUT; mongoc_stream_poll (&poller, 1, tls->timeout_msec); } else if (read_ret < 0) { RETURN (ret); } else { iov_pos += read_ret; ret += read_ret; } if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { if (read_ret == 0) { mongoc_counter_streams_timeout_inc (); errno = ETIMEDOUT; RETURN (-1); } tls->timeout_msec = 0; } else { tls->timeout_msec = (expire - now) / 1000L; } } if (ret > 0 && (size_t) ret >= min_bytes) { mongoc_counter_streams_ingress_add (ret); RETURN (ret); } } } if (ret >= 0) { mongoc_counter_streams_ingress_add (ret); } RETURN (ret); } static int _mongoc_stream_tls_libressl_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, mongoc_socklen_t optlen) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; ENTRY; BSON_ASSERT (libressl); RETURN (mongoc_stream_setsockopt ( tls->base_stream, level, optname, optval, optlen)); } static mongoc_stream_t * _mongoc_stream_tls_libressl_get_base_stream (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; ENTRY; BSON_ASSERT (libressl); RETURN (tls->base_stream); } static bool _mongoc_stream_tls_libressl_check_closed (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; ENTRY; BSON_ASSERT (libressl); RETURN (mongoc_stream_check_closed (tls->base_stream)); } bool mongoc_stream_tls_libressl_handshake (mongoc_stream_t *stream, const char *host, int *events, bson_error_t *error) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_libressl_t *libressl = (mongoc_stream_tls_libressl_t *) tls->ctx; int ret; ENTRY; BSON_ASSERT (libressl); ret = tls_handshake (libressl->ctx); if (ret == TLS_WANT_POLLIN) { *events = POLLIN; } else if (ret == TLS_WANT_POLLOUT) { *events = POLLOUT; } else if (ret < 0) { *events = 0; bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake failed: %s", tls_error (libressl->ctx)); RETURN (false); } else { RETURN (true); } RETURN (false); } static bool _mongoc_stream_tls_libressl_timed_out (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; ENTRY; RETURN (mongoc_stream_timed_out (tls->base_stream)); } mongoc_stream_t * mongoc_stream_tls_libressl_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { mongoc_stream_tls_t *tls; mongoc_stream_tls_libressl_t *libressl; ENTRY; BSON_ASSERT (base_stream); BSON_ASSERT (opt); if (opt->crl_file) { MONGOC_ERROR ( "Setting mongoc_ssl_opt_t.crl_file has no effect when built " "against libtls"); RETURN (false); } libressl = (mongoc_stream_tls_libressl_t *) bson_malloc0 (sizeof *libressl); tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); tls->parent.type = MONGOC_STREAM_TLS; tls->parent.destroy = _mongoc_stream_tls_libressl_destroy; tls->parent.failed = _mongoc_stream_tls_libressl_failed; tls->parent.close = _mongoc_stream_tls_libressl_close; tls->parent.flush = _mongoc_stream_tls_libressl_flush; tls->parent.writev = _mongoc_stream_tls_libressl_writev; tls->parent.readv = _mongoc_stream_tls_libressl_readv; tls->parent.setsockopt = _mongoc_stream_tls_libressl_setsockopt; tls->parent.get_base_stream = _mongoc_stream_tls_libressl_get_base_stream; tls->parent.check_closed = _mongoc_stream_tls_libressl_check_closed; tls->parent.timed_out = _mongoc_stream_tls_libressl_timed_out; memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); tls->handshake = mongoc_stream_tls_libressl_handshake; tls->ctx = (void *) libressl; tls->timeout_msec = -1; tls->base_stream = base_stream; libressl->ctx = client ? tls_client () : tls_server (); libressl->config = tls_config_new (); if (opt->weak_cert_validation) { tls_config_insecure_noverifycert (libressl->config); tls_config_insecure_noverifytime (libressl->config); } if (opt->allow_invalid_hostname) { tls_config_insecure_noverifyname (libressl->config); } tls_config_set_ciphers (libressl->config, "compat"); mongoc_libressl_setup_certificate (libressl, opt); mongoc_libressl_setup_ca (libressl, opt); { mongoc_stream_t *stream = base_stream; do { if (stream->type == MONGOC_STREAM_SOCKET) { int socket = mongoc_stream_socket_get_socket ( (mongoc_stream_socket_t *) stream) ->sd; if (tls_configure (libressl->ctx, libressl->config) == -1) { MONGOC_ERROR ("%s", tls_config_error (libressl->config)); RETURN (false); } if (tls_connect_socket (libressl->ctx, socket, host) == -1) { MONGOC_ERROR ("%s", tls_error (libressl->ctx)); RETURN (false); } break; } } while ((stream = mongoc_stream_get_base_stream (stream))); } mongoc_counter_streams_active_inc (); RETURN ((mongoc_stream_t *) tls); } #endif /* MONGOC_ENABLE_SSL_LIBRESSL */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-libressl.h0000664000175000017500000000232313210321137025147 0ustar jmikolajmikola/* * Copyright 2016 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_LIBRESSL_H #define MONGOC_STREAM_TLS_LIBRESSL_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_LIBRESSL #include #include "mongoc-macros.h" BSON_BEGIN_DECLS MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_tls_libressl_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client); BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_LIBRESSL */ #endif /* MONGOC_STREAM_TLS_LIBRESSL_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio-private.h0000664000175000017500000000317313210321137027236 0ustar jmikolajmikola/* * Copyright 2016 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_OPENSSL_BIO_PRIVATE_H #define MONGOC_STREAM_TLS_OPENSSL_BIO_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_OPENSSL #include #include #include #include BSON_BEGIN_DECLS BIO_METHOD * mongoc_stream_tls_openssl_bio_meth_new (); void mongoc_stream_tls_openssl_bio_set_data (BIO *b, void *ptr); int mongoc_stream_tls_openssl_bio_create (BIO *b); int mongoc_stream_tls_openssl_bio_destroy (BIO *b); int mongoc_stream_tls_openssl_bio_read (BIO *b, char *buf, int len); int mongoc_stream_tls_openssl_bio_write (BIO *b, const char *buf, int len); long mongoc_stream_tls_openssl_bio_ctrl (BIO *b, int cmd, long num, void *ptr); int mongoc_stream_tls_openssl_bio_gets (BIO *b, char *buf, int len); int mongoc_stream_tls_openssl_bio_puts (BIO *b, const char *str); BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_OPENSSL */ #endif /* MONGOC_STREAM_TLS_OPENSSL_BIO_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-bio.c0000664000175000017500000001675213210321137025570 0ustar jmikolajmikola/* * Copyright 2016 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_OPENSSL #include #include #include #include "mongoc-counters-private.h" #include "mongoc-errno-private.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-private.h" #include "mongoc-stream-tls-private.h" #include "mongoc-stream-tls-openssl-bio-private.h" #include "mongoc-stream-tls-openssl-private.h" #include "mongoc-openssl-private.h" #include "mongoc-trace-private.h" #include "mongoc-log.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-tls-openssl-bio" #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) /* Magic vtable to make our BIO shim */ static BIO_METHOD gMongocStreamTlsOpenSslRawMethods = { BIO_TYPE_FILTER, "mongoc-stream-tls-glue", mongoc_stream_tls_openssl_bio_write, mongoc_stream_tls_openssl_bio_read, mongoc_stream_tls_openssl_bio_puts, mongoc_stream_tls_openssl_bio_gets, mongoc_stream_tls_openssl_bio_ctrl, mongoc_stream_tls_openssl_bio_create, mongoc_stream_tls_openssl_bio_destroy, NULL}; static void BIO_set_data (BIO *b, void *ptr) { b->ptr = ptr; } static void * BIO_get_data (BIO *b) { return b->ptr; } static void BIO_set_init (BIO *b, int init) { b->init = init; } BIO_METHOD * mongoc_stream_tls_openssl_bio_meth_new () { BIO_METHOD *meth = NULL; meth = &gMongocStreamTlsOpenSslRawMethods; return meth; } #else BIO_METHOD * mongoc_stream_tls_openssl_bio_meth_new () { BIO_METHOD *meth = NULL; meth = BIO_meth_new (BIO_TYPE_FILTER, "mongoc-stream-tls-glue"); if (meth) { BIO_meth_set_write (meth, mongoc_stream_tls_openssl_bio_write); BIO_meth_set_read (meth, mongoc_stream_tls_openssl_bio_read); BIO_meth_set_puts (meth, mongoc_stream_tls_openssl_bio_puts); BIO_meth_set_gets (meth, mongoc_stream_tls_openssl_bio_gets); BIO_meth_set_ctrl (meth, mongoc_stream_tls_openssl_bio_ctrl); BIO_meth_set_create (meth, mongoc_stream_tls_openssl_bio_create); BIO_meth_set_destroy (meth, mongoc_stream_tls_openssl_bio_destroy); } return meth; } #endif void mongoc_stream_tls_openssl_bio_set_data (BIO *b, void *ptr) { BIO_set_data (b, ptr); } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_openssl_bio_create -- * * BIO callback to create a new BIO instance. * * Returns: * 1 if successful. * * Side effects: * @b is initialized. * *-------------------------------------------------------------------------- */ int mongoc_stream_tls_openssl_bio_create (BIO *b) { BSON_ASSERT (b); BIO_set_init (b, 1); BIO_set_data (b, NULL); BIO_set_flags (b, 0); return 1; } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_openssl_bio_destroy -- * * Release resources associated with BIO. * * Returns: * 1 if successful. * * Side effects: * @b is destroyed. * *-------------------------------------------------------------------------- */ int mongoc_stream_tls_openssl_bio_destroy (BIO *b) { mongoc_stream_tls_t *tls; BSON_ASSERT (b); tls = (mongoc_stream_tls_t *) BIO_get_data (b); if (!tls) { return -1; } BIO_set_data (b, NULL); BIO_set_init (b, 0); BIO_set_flags (b, 0); ((mongoc_stream_tls_openssl_t *) tls->ctx)->bio = NULL; return 1; } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_openssl_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. * *-------------------------------------------------------------------------- */ int mongoc_stream_tls_openssl_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 *) BIO_get_data (b); 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_openssl_bio_write -- * * Write to the underlying stream on behalf of BIO. * * Returns: * -1 on failure; otherwise the number of bytes written. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_stream_tls_openssl_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 *) BIO_get_data (b); 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_openssl_bio_ctrl -- * * Handle ctrl callback for BIO. * * Returns: * ioctl dependent. * * Side effects: * ioctl dependent. * *-------------------------------------------------------------------------- */ long mongoc_stream_tls_openssl_bio_ctrl (BIO *b, int cmd, long num, void *ptr) { switch (cmd) { case BIO_CTRL_FLUSH: return 1; default: return 0; } } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_openssl_bio_gets -- * * BIO callback for gets(). Not supported. * * Returns: * -1 always. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_stream_tls_openssl_bio_gets (BIO *b, char *buf, int len) { return -1; } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_openssl_bio_puts -- * * BIO callback to perform puts(). Just calls the actual write * callback. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_stream_tls_openssl_bio_puts (BIO *b, const char *str) { return mongoc_stream_tls_openssl_bio_write (b, str, (int) strlen (str)); } #endif /* MONGOC_ENABLE_SSL_OPENSSL */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl-private.h0000664000175000017500000000225213210321137026464 0ustar jmikolajmikola/* * Copyright 2016 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_OPENSSL_PRIVATE_H #define MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_OPENSSL #include BSON_BEGIN_DECLS /** * mongoc_stream_tls_openssl_t: * * Private storage for handling callbacks from mongoc_stream and BIO_* */ typedef struct { BIO *bio; BIO_METHOD *meth; SSL_CTX *ctx; } mongoc_stream_tls_openssl_t; BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_OPENSSL */ #endif /* MONGOC_STREAM_TLS_OPENSSL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c0000664000175000017500000005032413210321137025012 0ustar jmikolajmikola/* * Copyright 2016 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_OPENSSL #include #include #include #include #include #include #include #include "mongoc-counters-private.h" #include "mongoc-errno-private.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-private.h" #include "mongoc-stream-tls-private.h" #include "mongoc-stream-tls-openssl-bio-private.h" #include "mongoc-stream-tls-openssl-private.h" #include "mongoc-openssl-private.h" #include "mongoc-trace-private.h" #include "mongoc-log.h" #include "mongoc-error.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-tls-openssl" #define MONGOC_STREAM_TLS_OPENSSL_BUFFER_SIZE 4096 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) static void BIO_meth_free (BIO_METHOD *meth) { /* Nothing to free pre OpenSSL 1.1.0 */ } #endif /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_openssl_destroy -- * * Cleanup after usage of a mongoc_stream_tls_openssl_t. Free all *allocated * resources and ensure connections are closed. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _mongoc_stream_tls_openssl_destroy (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_openssl_t *openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; BSON_ASSERT (tls); BIO_free_all (openssl->bio); openssl->bio = NULL; BIO_meth_free (openssl->meth); openssl->meth = NULL; mongoc_stream_destroy (tls->base_stream); tls->base_stream = NULL; SSL_CTX_free (openssl->ctx); openssl->ctx = NULL; bson_free (openssl); bson_free (stream); mongoc_counter_streams_active_dec (); mongoc_counter_streams_disposed_inc (); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_openssl_failed -- * * Called on stream failure. Same as _mongoc_stream_tls_openssl_destroy() * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _mongoc_stream_tls_openssl_failed (mongoc_stream_t *stream) { _mongoc_stream_tls_openssl_destroy (stream); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_openssl_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_openssl_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_openssl_flush -- * * Flush the underlying stream. * * Returns: * 0 if successful; otherwise -1. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_openssl_flush (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_openssl_t *openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; BSON_ASSERT (openssl); return BIO_flush (openssl->bio); } static ssize_t _mongoc_stream_tls_openssl_write (mongoc_stream_tls_t *tls, char *buf, size_t buf_len) { mongoc_stream_tls_openssl_t *openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; 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 (openssl->bio, buf, buf_len); 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_openssl_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. * * This function is copied as _mongoc_stream_tls_secure_transport_writev *-------------------------------------------------------------------------- */ static ssize_t _mongoc_stream_tls_openssl_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_OPENSSL_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_OPENSSL_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_OPENSSL_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_openssl_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_openssl_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_openssl_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. * * This function is copied as _mongoc_stream_tls_secure_transport_readv * *-------------------------------------------------------------------------- */ static ssize_t _mongoc_stream_tls_openssl_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; mongoc_stream_tls_openssl_t *openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; 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 (openssl->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 (openssl->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_openssl_setsockopt -- * * Perform a setsockopt on the underlying stream. * * Returns: * -1 on failure, otherwise opt specific value. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_openssl_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, mongoc_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); } static mongoc_stream_t * _mongoc_stream_tls_openssl_get_base_stream (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; return tls->base_stream; } static bool _mongoc_stream_tls_openssl_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_openssl_handshake: */ bool mongoc_stream_tls_openssl_handshake (mongoc_stream_t *stream, const char *host, int *events, bson_error_t *error) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_openssl_t *openssl = (mongoc_stream_tls_openssl_t *) tls->ctx; SSL *ssl; BSON_ASSERT (tls); BSON_ASSERT (host); ENTRY; BIO_get_ssl (openssl->bio, &ssl); if (BIO_do_handshake (openssl->bio) == 1) { if (_mongoc_openssl_check_cert ( ssl, host, tls->ssl_opts.allow_invalid_hostname)) { RETURN (true); } *events = 0; bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake failed: Failed certificate verification"); RETURN (false); } if (BIO_should_retry (openssl->bio)) { *events = BIO_should_read (openssl->bio) ? POLLIN : POLLOUT; RETURN (false); } if (!errno) { #ifdef _WIN32 errno = WSAETIMEDOUT; #else errno = ETIMEDOUT; #endif } *events = 0; bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake failed: %s", ERR_error_string (ERR_get_error (), NULL)); RETURN (false); } /* Callback to get the client provided SNI, if any * It is only called in SSL "server mode" (e.g. when using the Mock Server), * and we don't actually use the hostname for anything, just debug print it */ static int _mongoc_stream_tls_openssl_sni (SSL *ssl, int *ad, void *arg) { const char *hostname; if (ssl == NULL) { MONGOC_DEBUG ("No SNI hostname provided"); return SSL_TLSEXT_ERR_NOACK; } hostname = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name); MONGOC_DEBUG ("Got SNI: '%s'", hostname); return SSL_TLSEXT_ERR_OK; } static bool _mongoc_stream_tls_openssl_timed_out (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; ENTRY; RETURN (mongoc_stream_timed_out (tls->base_stream)); } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_openssl_new -- * * Creates a new mongoc_stream_tls_openssl_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_openssl_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { mongoc_stream_tls_t *tls; mongoc_stream_tls_openssl_t *openssl; SSL_CTX *ssl_ctx = NULL; BIO *bio_ssl = NULL; BIO *bio_mongoc_shim = NULL; BIO_METHOD *meth; BSON_ASSERT (base_stream); BSON_ASSERT (opt); ENTRY; ssl_ctx = _mongoc_openssl_ctx_new (opt); if (!ssl_ctx) { RETURN (NULL); } #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) if (!opt->allow_invalid_hostname) { struct in_addr addr; X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new (); X509_VERIFY_PARAM_set_hostflags (param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); if (inet_pton (AF_INET, host, &addr) || inet_pton (AF_INET6, host, &addr)) { X509_VERIFY_PARAM_set1_ip_asc (param, host); } else { X509_VERIFY_PARAM_set1_host (param, host, 0); } SSL_CTX_set1_param (ssl_ctx, param); X509_VERIFY_PARAM_free (param); } #endif if (!client) { /* Only usd by the Mock Server. * Set a callback to get the SNI, if provided */ SSL_CTX_set_tlsext_servername_callback (ssl_ctx, _mongoc_stream_tls_openssl_sni); } if (opt->weak_cert_validation) { SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL); } else { SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER, NULL); } bio_ssl = BIO_new_ssl (ssl_ctx, client); if (!bio_ssl) { SSL_CTX_free (ssl_ctx); RETURN (NULL); } meth = mongoc_stream_tls_openssl_bio_meth_new (); bio_mongoc_shim = BIO_new (meth); if (!bio_mongoc_shim) { BIO_free_all (bio_ssl); BIO_meth_free (meth); RETURN (NULL); } /* Added in OpenSSL 0.9.8f, as a build time option */ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME if (client) { SSL *ssl; /* Set the SNI hostname we are expecting certificate for */ BIO_get_ssl (bio_ssl, &ssl); SSL_set_tlsext_host_name (ssl, host); #endif } BIO_push (bio_ssl, bio_mongoc_shim); openssl = (mongoc_stream_tls_openssl_t *) bson_malloc0 (sizeof *openssl); openssl->bio = bio_ssl; openssl->meth = meth; openssl->ctx = ssl_ctx; tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); tls->parent.type = MONGOC_STREAM_TLS; tls->parent.destroy = _mongoc_stream_tls_openssl_destroy; tls->parent.failed = _mongoc_stream_tls_openssl_failed; tls->parent.close = _mongoc_stream_tls_openssl_close; tls->parent.flush = _mongoc_stream_tls_openssl_flush; tls->parent.writev = _mongoc_stream_tls_openssl_writev; tls->parent.readv = _mongoc_stream_tls_openssl_readv; tls->parent.setsockopt = _mongoc_stream_tls_openssl_setsockopt; tls->parent.get_base_stream = _mongoc_stream_tls_openssl_get_base_stream; tls->parent.check_closed = _mongoc_stream_tls_openssl_check_closed; tls->parent.timed_out = _mongoc_stream_tls_openssl_timed_out; memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); tls->handshake = mongoc_stream_tls_openssl_handshake; tls->ctx = (void *) openssl; tls->timeout_msec = -1; tls->base_stream = base_stream; mongoc_stream_tls_openssl_bio_set_data (bio_mongoc_shim, tls); mongoc_counter_streams_active_inc (); RETURN ((mongoc_stream_t *) tls); } #endif /* MONGOC_ENABLE_SSL_OPENSSL */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.h0000664000175000017500000000231113210321137025010 0ustar jmikolajmikola/* * Copyright 2016 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_OPENSSL_H #define MONGOC_STREAM_TLS_OPENSSL_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_OPENSSL #include #include "mongoc-macros.h" BSON_BEGIN_DECLS MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_tls_openssl_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client); BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_OPENSSL */ #endif /* MONGOC_STREAM_TLS_OPENSSL_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-private.h0000664000175000017500000000276113210321137025010 0ustar jmikolajmikola/* * Copyright 2016 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_PRIVATE_H #define MONGOC_STREAM_TLS_PRIVATE_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 /** * mongoc_stream_tls_t: * * Overloaded mongoc_stream_t with additional TLS handshake and verification * callbacks. * */ struct _mongoc_stream_tls_t { mongoc_stream_t parent; /* The TLS stream wrapper */ mongoc_stream_t *base_stream; /* The underlying actual stream */ void *ctx; /* TLS lib specific configuration or wrappers */ int32_t timeout_msec; mongoc_ssl_opt_t ssl_opts; bool (*handshake) (mongoc_stream_t *stream, const char *host, int *events /* OUT*/, bson_error_t *error); }; BSON_END_DECLS #endif /* MONGOC_STREAM_TLS_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel-private.h0000664000175000017500000000450513210321137027700 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_CHANNEL_PRIVATE_H #define MONGOC_STREAM_TLS_SECURE_CHANNEL_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL #include /* Its mandatory to indicate to Windows who is compiling the code */ #define SECURITY_WIN32 #include BSON_BEGIN_DECLS /* enum for the nonblocking SSL connection state machine */ typedef enum { ssl_connect_1, ssl_connect_2, ssl_connect_2_reading, ssl_connect_2_writing, ssl_connect_3, ssl_connect_done } ssl_connect_state; /* Structs to store Schannel handles */ typedef struct { CredHandle cred_handle; TimeStamp time_stamp; } mongoc_secure_channel_cred; typedef struct { CtxtHandle ctxt_handle; TimeStamp time_stamp; } mongoc_secure_channel_ctxt; /** * mongoc_stream_tls_secure_channel_t: * * Private storage for Secure Channel Streams */ typedef struct { ssl_connect_state connecting_state; mongoc_secure_channel_cred *cred; mongoc_secure_channel_ctxt *ctxt; SecPkgContext_StreamSizes stream_sizes; size_t encdata_length, decdata_length; size_t encdata_offset, decdata_offset; unsigned char *encdata_buffer, *decdata_buffer; unsigned long req_flags, ret_flags; int recv_unrecoverable_err; /* _mongoc_stream_tls_secure_channel_read had an unrecoverable err */ bool recv_sspi_close_notify; /* true if connection closed by close_notify */ bool recv_connection_closed; /* true if connection closed, regardless how */ } mongoc_stream_tls_secure_channel_t; BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_SECURE_CHANNEL */ #endif /* MONGOC_STREAM_TLS_SECURE_CHANNEL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.c0000664000175000017500000011200213210321137026213 0ustar jmikolajmikola/* * Copyright 2016 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. */ /** * Significant portion of this file, such as * _mongoc_stream_tls_secure_channel_write & *_mongoc_stream_tls_secure_channel_read * comes straight from one of my favorite projects, cURL! * Thank you so much for having gone through the Secure Channel pain for me. * * * Copyright (C) 2012 - 2015, Marc Hoersken, * Copyright (C) 2012, Mark Salisbury, * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ***************************************************************************/ /* * Based upon the PolarSSL implementation in polarssl.c and polarssl.h: * Copyright (C) 2010, 2011, Hoi-Ho Chan, * * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. * * Thanks for code and inspiration! */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL #include #include "mongoc-trace-private.h" #include "mongoc-log.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-tls-private.h" #include "mongoc-stream-private.h" #include "mongoc-stream-tls-secure-channel-private.h" #include "mongoc-secure-channel-private.h" #include "mongoc-ssl.h" #include "mongoc-error.h" #include "mongoc-counters-private.h" #include "mongoc-errno-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-tls-secure-channel" #define SECURITY_WIN32 #include #include #include /* mingw doesn't define these */ #ifndef SP_PROT_TLS1_1_CLIENT #define SP_PROT_TLS1_1_CLIENT 0x00000200 #endif #ifndef SP_PROT_TLS1_2_CLIENT #define SP_PROT_TLS1_2_CLIENT 0x00000800 #endif size_t mongoc_secure_channel_write (mongoc_stream_tls_t *tls, const void *data, size_t data_length); static void _mongoc_stream_tls_secure_channel_destroy (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_channel); /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx * Shutting Down an Schannel Connection */ TRACE ("shutting down SSL/TLS connection"); if (secure_channel->cred && secure_channel->ctxt) { SecBufferDesc BuffDesc; SecBuffer Buffer; SECURITY_STATUS sspi_status; SecBuffer outbuf; SecBufferDesc outbuf_desc; DWORD dwshut = SCHANNEL_SHUTDOWN; _mongoc_secure_channel_init_sec_buffer ( &Buffer, SECBUFFER_TOKEN, &dwshut, sizeof (dwshut)); _mongoc_secure_channel_init_sec_buffer_desc (&BuffDesc, &Buffer, 1); sspi_status = ApplyControlToken (&secure_channel->ctxt->ctxt_handle, &BuffDesc); if (sspi_status != SEC_E_OK) { MONGOC_ERROR ("ApplyControlToken failure: %d", sspi_status); } /* setup output buffer */ _mongoc_secure_channel_init_sec_buffer ( &outbuf, SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, &outbuf, 1); sspi_status = InitializeSecurityContext (&secure_channel->cred->cred_handle, &secure_channel->ctxt->ctxt_handle, /*tls->hostname*/ NULL, secure_channel->req_flags, 0, 0, NULL, 0, &secure_channel->ctxt->ctxt_handle, &outbuf_desc, &secure_channel->ret_flags, &secure_channel->ctxt->time_stamp); if ((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { /* send close message which is in output buffer */ ssize_t written = mongoc_secure_channel_write (tls, outbuf.pvBuffer, outbuf.cbBuffer); FreeContextBuffer (outbuf.pvBuffer); if (outbuf.cbBuffer != (size_t) written) { TRACE ("failed to send close msg (wrote %zd out of %zd)", written, outbuf.cbBuffer); } } } /* free SSPI Schannel API security context handle */ if (secure_channel->ctxt) { TRACE ("clear security context handle"); DeleteSecurityContext (&secure_channel->ctxt->ctxt_handle); bson_free (secure_channel->ctxt); } /* free SSPI Schannel API credential handle */ if (secure_channel->cred) { /* decrement the reference counter of the credential/session handle */ /* if the handle was not cached and the refcount is zero */ TRACE ("clear credential handle"); FreeCredentialsHandle (&secure_channel->cred->cred_handle); bson_free (secure_channel->cred); } /* free internal buffer for received encrypted data */ if (secure_channel->encdata_buffer != NULL) { bson_free (secure_channel->encdata_buffer); secure_channel->encdata_length = 0; secure_channel->encdata_offset = 0; } /* free internal buffer for received decrypted data */ if (secure_channel->decdata_buffer != NULL) { bson_free (secure_channel->decdata_buffer); secure_channel->decdata_length = 0; secure_channel->decdata_offset = 0; } mongoc_stream_destroy (tls->base_stream); bson_free (secure_channel); bson_free (stream); mongoc_counter_streams_active_dec (); mongoc_counter_streams_disposed_inc (); EXIT; } static void _mongoc_stream_tls_secure_channel_failed (mongoc_stream_t *stream) { ENTRY; _mongoc_stream_tls_secure_channel_destroy (stream); EXIT; } static int _mongoc_stream_tls_secure_channel_close (mongoc_stream_t *stream) { int ret = 0; mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_channel); ret = mongoc_stream_close (tls->base_stream); RETURN (ret); } static int _mongoc_stream_tls_secure_channel_flush (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_channel); RETURN (0); } static ssize_t _mongoc_stream_tls_secure_channel_write (mongoc_stream_t *stream, char *buf, size_t buf_len) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ssize_t written = -1; size_t data_len = 0; unsigned char *data = NULL; SecBuffer outbuf[4]; SecBufferDesc outbuf_desc; SECURITY_STATUS sspi_status = SEC_E_OK; ENTRY; BSON_ASSERT (secure_channel); TRACE ("The entire buffer is: %d", buf_len); /* check if the maximum stream sizes were queried */ if (secure_channel->stream_sizes.cbMaximumMessage == 0) { sspi_status = QueryContextAttributes (&secure_channel->ctxt->ctxt_handle, SECPKG_ATTR_STREAM_SIZES, &secure_channel->stream_sizes); if (sspi_status != SEC_E_OK) { TRACE ("failing here: %d", __LINE__); return -1; } } /* check if the buffer is longer than the maximum message length */ if (buf_len > secure_channel->stream_sizes.cbMaximumMessage) { TRACE ("SHRINKING buf_len from %lu to %lu", buf_len, secure_channel->stream_sizes.cbMaximumMessage); buf_len = secure_channel->stream_sizes.cbMaximumMessage; } /* calculate the complete message length and allocate a buffer for it */ data_len = secure_channel->stream_sizes.cbHeader + buf_len + secure_channel->stream_sizes.cbTrailer; data = (unsigned char *) bson_malloc (data_len); /* setup output buffers (header, data, trailer, empty) */ _mongoc_secure_channel_init_sec_buffer ( &outbuf[0], SECBUFFER_STREAM_HEADER, data, secure_channel->stream_sizes.cbHeader); _mongoc_secure_channel_init_sec_buffer ( &outbuf[1], SECBUFFER_DATA, data + secure_channel->stream_sizes.cbHeader, (unsigned long) (buf_len & (size_t) 0xFFFFFFFFUL)); _mongoc_secure_channel_init_sec_buffer ( &outbuf[2], SECBUFFER_STREAM_TRAILER, data + secure_channel->stream_sizes.cbHeader + buf_len, secure_channel->stream_sizes.cbTrailer); _mongoc_secure_channel_init_sec_buffer ( &outbuf[3], SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer_desc (&outbuf_desc, outbuf, 4); /* copy data into output buffer */ memcpy (outbuf[1].pvBuffer, buf, buf_len); /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */ sspi_status = EncryptMessage (&secure_channel->ctxt->ctxt_handle, 0, &outbuf_desc, 0); /* check if the message was encrypted */ if (sspi_status == SEC_E_OK) { written = 0; /* send the encrypted message including header, data and trailer */ buf_len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer; written = mongoc_secure_channel_write (tls, data, buf_len); } else { written = -1; } bson_free (data); if (buf_len == (size_t) written) { /* Encrypted message including header, data and trailer entirely sent. * The return value is the number of unencrypted bytes that were sent. */ written = outbuf[1].cbBuffer; } return written; } /* This is copypasta from _mongoc_stream_tls_openssl_writev */ #define MONGOC_STREAM_TLS_BUFFER_SIZE 4096 static ssize_t _mongoc_stream_tls_secure_channel_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; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; 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 (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (secure_channel); ENTRY; TRACE ("Trying to write to the server"); tls->timeout_msec = timeout_msec; TRACE ("count: %d, 0th: %lu", iovcnt, iov[0].iov_len); for (i = 0; i < iovcnt; i++) { iov_pos = 0; TRACE ("iov %d size: %lu", i, iov[i].iov_len); 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_secure_channel_write ( stream, to_write, to_write_len); TRACE ("Child0wrote: %d, was supposed to write: %d", child_ret, to_write_len); if (child_ret < 0) { RETURN (ret); } ret += child_ret; iov_pos -= to_write_len - child_ret; to_write = NULL; } } } if (buf_head != buf_tail) { /* If we have any bytes buffered, send */ child_ret = _mongoc_stream_tls_secure_channel_write ( stream, buf_head, buf_tail - buf_head); TRACE ("Child1wrote: %d, was supposed to write: %d", child_ret, buf_tail - buf_head); if (child_ret < 0) { RETURN (child_ret); } ret += child_ret; } if (ret >= 0) { mongoc_counter_streams_egress_add (ret); } TRACE ("Returning %zu", ret); RETURN (ret); } static ssize_t _mongoc_stream_tls_secure_channel_read (mongoc_stream_t *stream, char *buf, size_t len) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ssize_t error = 0; size_t size = 0; ssize_t nread = -1; unsigned char *reallocated_buffer; size_t reallocated_length; bool done = false; SecBuffer inbuf[4]; SecBufferDesc inbuf_desc; SECURITY_STATUS sspi_status = SEC_E_OK; /* we want the length of the encrypted buffer to be at least large enough * that it can hold all the bytes requested and some TLS record overhead. */ size_t min_encdata_length = len + MONGOC_SCHANNEL_BUFFER_FREE_SIZE; /**************************************************************************** * Don't return or set secure_channel->recv_unrecoverable_err unless in the * cleanup. * The pattern for return error is set error, optional infof, goto cleanup. * * Our priority is to always return as much decrypted data to the caller as * possible, even if an error occurs. The state of the decrypted buffer must * always be valid. Transfer of decrypted data to the caller's buffer is * handled in the cleanup. */ TRACE ("client wants to read %zu bytes", len); if (len && len <= secure_channel->decdata_offset) { TRACE ("enough decrypted data is already available"); goto cleanup; } else if (secure_channel->recv_unrecoverable_err) { error = secure_channel->recv_unrecoverable_err; TRACE ("an unrecoverable error occurred in a prior call"); goto cleanup; } else if (secure_channel->recv_sspi_close_notify) { /* once a server has indicated shutdown there is no more encrypted data */ TRACE ("server indicated shutdown in a prior call"); goto cleanup; } else if (!len) { /* It's debatable what to return when !len. Regardless we can't return * immediately because there may be data to decrypt (in the case we want * to * decrypt all encrypted cached data) so handle !len later in cleanup. */ /* do nothing */ } else if (!secure_channel->recv_connection_closed) { /* increase enc buffer in order to fit the requested amount of data */ size = secure_channel->encdata_length - secure_channel->encdata_offset; if (size < MONGOC_SCHANNEL_BUFFER_FREE_SIZE || secure_channel->encdata_length < min_encdata_length) { reallocated_length = secure_channel->encdata_offset + MONGOC_SCHANNEL_BUFFER_FREE_SIZE; if (reallocated_length < min_encdata_length) { reallocated_length = min_encdata_length; } reallocated_buffer = bson_realloc (secure_channel->encdata_buffer, reallocated_length); secure_channel->encdata_buffer = reallocated_buffer; secure_channel->encdata_length = reallocated_length; size = secure_channel->encdata_length - secure_channel->encdata_offset; TRACE ("encdata_buffer resized %zu", secure_channel->encdata_length); } TRACE ("encrypted data buffer: offset %zu length %zu", secure_channel->encdata_offset, secure_channel->encdata_length); /* read encrypted data from socket */ nread = mongoc_secure_channel_read (tls, (char *) (secure_channel->encdata_buffer + secure_channel->encdata_offset), size); if (!nread) { nread = -1; if (MONGOC_ERRNO_IS_AGAIN (errno)) { TRACE ("Try again"); error = EAGAIN; } else { secure_channel->recv_connection_closed = true; TRACE ("reading failed: %d", errno); } } else { secure_channel->encdata_offset += (size_t) nread; TRACE ("encrypted data got %zd", nread); } } TRACE ("encrypted data buffer: offset %zu length %zu", secure_channel->encdata_offset, secure_channel->encdata_length); /* decrypt loop */ while (secure_channel->encdata_offset > 0 && sspi_status == SEC_E_OK && (!len || secure_channel->decdata_offset < len || secure_channel->recv_connection_closed)) { /* prepare data buffer for DecryptMessage call */ _mongoc_secure_channel_init_sec_buffer ( &inbuf[0], SECBUFFER_DATA, secure_channel->encdata_buffer, (unsigned long) (secure_channel->encdata_offset & (size_t) 0xFFFFFFFFUL)); /* we need 3 more empty input buffers for possible output */ _mongoc_secure_channel_init_sec_buffer ( &inbuf[1], SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer ( &inbuf[2], SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer ( &inbuf[3], SECBUFFER_EMPTY, NULL, 0); _mongoc_secure_channel_init_sec_buffer_desc (&inbuf_desc, inbuf, 4); /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx */ sspi_status = DecryptMessage ( &secure_channel->ctxt->ctxt_handle, &inbuf_desc, 0, NULL); /* check if everything went fine (server may want to renegotiate * or shutdown the connection context) */ if (sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE || sspi_status == SEC_I_CONTEXT_EXPIRED) { /* check for successfully decrypted data, even before actual * renegotiation or shutdown of the connection context */ if (inbuf[1].BufferType == SECBUFFER_DATA) { TRACE ("decrypted data length: %lu", inbuf[1].cbBuffer); /* increase buffer in order to fit the received amount of data */ size = inbuf[1].cbBuffer > MONGOC_SCHANNEL_BUFFER_FREE_SIZE ? inbuf[1].cbBuffer : MONGOC_SCHANNEL_BUFFER_FREE_SIZE; if (secure_channel->decdata_length - secure_channel->decdata_offset < size || secure_channel->decdata_length < len) { /* increase internal decrypted data buffer */ reallocated_length = secure_channel->decdata_offset + size; /* make sure that the requested amount of data fits */ if (reallocated_length < len) { reallocated_length = len; } reallocated_buffer = bson_realloc ( secure_channel->decdata_buffer, reallocated_length); secure_channel->decdata_buffer = reallocated_buffer; secure_channel->decdata_length = reallocated_length; } /* copy decrypted data to internal buffer */ size = inbuf[1].cbBuffer; if (size) { memcpy (secure_channel->decdata_buffer + secure_channel->decdata_offset, inbuf[1].pvBuffer, size); secure_channel->decdata_offset += size; } TRACE ("decrypted data added: %zu", size); TRACE ("decrypted data cached: offset %zu length %zu", secure_channel->decdata_offset, secure_channel->decdata_length); } /* check for remaining encrypted data */ if (inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { TRACE ("encrypted data length: %lu", inbuf[3].cbBuffer); /* check if the remaining data is less than the total amount * and therefore begins after the already processed data */ if (secure_channel->encdata_offset > inbuf[3].cbBuffer) { /* move remaining encrypted data forward to the beginning of * buffer */ memmove (secure_channel->encdata_buffer, (secure_channel->encdata_buffer + secure_channel->encdata_offset) - inbuf[3].cbBuffer, inbuf[3].cbBuffer); secure_channel->encdata_offset = inbuf[3].cbBuffer; } TRACE ("encrypted data cached: offset %zu length %zu", secure_channel->encdata_offset, secure_channel->encdata_length); } else { /* reset encrypted buffer offset, because there is no data remaining */ secure_channel->encdata_offset = 0; } /* check if server wants to renegotiate the connection context */ if (sspi_status == SEC_I_RENEGOTIATE) { TRACE ("remote party requests renegotiation"); goto cleanup; } /* check if the server closed the connection */ else if (sspi_status == SEC_I_CONTEXT_EXPIRED) { /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not * returned so we have to work around that in cleanup. */ secure_channel->recv_sspi_close_notify = true; if (!secure_channel->recv_connection_closed) { secure_channel->recv_connection_closed = true; TRACE ("server closed the connection"); } goto cleanup; } } else if (sspi_status == SEC_E_INCOMPLETE_MESSAGE) { if (!error) { error = EAGAIN; } TRACE ("failed to decrypt data, need more data"); goto cleanup; } else { error = 1; TRACE ("failed to read data from server: %d", sspi_status); goto cleanup; } } TRACE ("encrypted data buffer: offset %zu length %zu", secure_channel->encdata_offset, secure_channel->encdata_length); TRACE ("decrypted data buffer: offset %zu length %zu", secure_channel->decdata_offset, secure_channel->decdata_length); cleanup: /* Warning- there is no guarantee the encdata state is valid at this point */ TRACE ("cleanup"); /* Error if the connection has closed without a close_notify. * Behavior here is a matter of debate. We don't want to be vulnerable to a * truncation attack however there's some browser precedent for ignoring the * close_notify for compatibility reasons. * Additionally, Windows 2000 (v5.0) is a special case since it seems it * doesn't * return close_notify. In that case if the connection was closed we assume * it * was graceful (close_notify) since there doesn't seem to be a way to tell. */ if (len && !secure_channel->decdata_offset && secure_channel->recv_connection_closed && !secure_channel->recv_sspi_close_notify) { error = 1; TRACE ("server closed abruptly (missing close_notify)"); } /* Any error other than EAGAIN is an unrecoverable error. */ if (error && error != EAGAIN) { secure_channel->recv_unrecoverable_err = error; TRACE ("fatal error"); } size = len < secure_channel->decdata_offset ? len : secure_channel->decdata_offset; if (size) { memcpy (buf, secure_channel->decdata_buffer, size); memmove (secure_channel->decdata_buffer, secure_channel->decdata_buffer + size, secure_channel->decdata_offset - size); secure_channel->decdata_offset -= size; TRACE ("decrypted data returned %zu", size); TRACE ("decrypted data buffer: offset %zu length %zu", secure_channel->decdata_offset, secure_channel->decdata_length); return (ssize_t) size; } if (!error && !secure_channel->recv_connection_closed) { error = EAGAIN; } /* It's debatable what to return when !len. We could return whatever error we * got from decryption but instead we override here so the return is * consistent. */ if (!len) { error = 0; } if (error == EAGAIN) { errno = EAGAIN; return 0; } TRACE ("error is: %d and errno is: %d", error, errno); return error ? -1 : 0; } /* This function is copypasta of _mongoc_stream_tls_openssl_readv */ static ssize_t _mongoc_stream_tls_secure_channel_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; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ssize_t ret = 0; size_t i; size_t iov_pos = 0; int64_t now; int64_t expire = 0; BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (secure_channel); ENTRY; 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) { ssize_t read_ret = _mongoc_stream_tls_secure_channel_read ( stream, (char *) iov[i].iov_base + iov_pos, (int) (iov[i].iov_len - iov_pos)); if (read_ret < 0) { RETURN (-1); } if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { if (read_ret == 0) { mongoc_counter_streams_timeout_inc (); errno = ETIMEDOUT; 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); } static int _mongoc_stream_tls_secure_channel_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, mongoc_socklen_t optlen) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_channel); RETURN (mongoc_stream_setsockopt ( tls->base_stream, level, optname, optval, optlen)); } static mongoc_stream_t * _mongoc_stream_tls_secure_channel_get_base_stream (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_channel); RETURN (tls->base_stream); } static bool _mongoc_stream_tls_secure_channel_check_closed ( mongoc_stream_t *stream) /* IN */ { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_channel); RETURN (mongoc_stream_check_closed (tls->base_stream)); } bool mongoc_stream_tls_secure_channel_handshake (mongoc_stream_t *stream, const char *host, int *events, bson_error_t *error) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_channel_t *secure_channel = (mongoc_stream_tls_secure_channel_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_channel); TRACE ("Getting ready for state: %d", secure_channel->connecting_state + 1); switch (secure_channel->connecting_state) { case ssl_connect_1: if (mongoc_secure_channel_handshake_step_1 (tls, (char *) host)) { TRACE ("Step#1 Worked!\n\n"); *events = POLLIN; RETURN (false); } else { TRACE ("Step#1 FAILED!"); } break; case ssl_connect_2: case ssl_connect_2_reading: case ssl_connect_2_writing: if (mongoc_secure_channel_handshake_step_2 (tls, (char *) host)) { TRACE ("Step#2 Worked!\n\n"); *events = POLLIN | POLLOUT; RETURN (false); } else { TRACE ("Step#2 FAILED!"); } break; case ssl_connect_3: if (mongoc_secure_channel_handshake_step_3 (tls, (char *) host)) { TRACE ("Step#3 Worked!\n\n"); *events = POLLIN | POLLOUT; RETURN (false); } else { TRACE ("Step#3 FAILED!"); } break; case ssl_connect_done: TRACE ("Connect DONE!"); /* reset our connection state machine */ secure_channel->connecting_state = ssl_connect_1; RETURN (true); break; } *events = 0; bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake failed"); RETURN (false); } static bool _mongoc_stream_tls_secure_channel_timed_out (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; ENTRY; RETURN (mongoc_stream_timed_out (tls->base_stream)); } mongoc_stream_t * mongoc_stream_tls_secure_channel_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { SECURITY_STATUS sspi_status = SEC_E_OK; SCHANNEL_CRED schannel_cred; mongoc_stream_tls_t *tls; mongoc_stream_tls_secure_channel_t *secure_channel; ENTRY; BSON_ASSERT (base_stream); BSON_ASSERT (opt); secure_channel = (mongoc_stream_tls_secure_channel_t *) bson_malloc0 ( sizeof *secure_channel); tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); tls->parent.type = MONGOC_STREAM_TLS; tls->parent.destroy = _mongoc_stream_tls_secure_channel_destroy; tls->parent.failed = _mongoc_stream_tls_secure_channel_failed; tls->parent.close = _mongoc_stream_tls_secure_channel_close; tls->parent.flush = _mongoc_stream_tls_secure_channel_flush; tls->parent.writev = _mongoc_stream_tls_secure_channel_writev; tls->parent.readv = _mongoc_stream_tls_secure_channel_readv; tls->parent.setsockopt = _mongoc_stream_tls_secure_channel_setsockopt; tls->parent.get_base_stream = _mongoc_stream_tls_secure_channel_get_base_stream; tls->parent.check_closed = _mongoc_stream_tls_secure_channel_check_closed; tls->parent.timed_out = _mongoc_stream_tls_secure_channel_timed_out; memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); tls->handshake = mongoc_stream_tls_secure_channel_handshake; tls->ctx = (void *) secure_channel; tls->timeout_msec = -1; tls->base_stream = base_stream; TRACE ("SSL/TLS connection with endpoint AcquireCredentialsHandle"); /* setup Schannel API options */ memset (&schannel_cred, 0, sizeof (schannel_cred)); schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; /* SCHANNEL_CRED: * SCH_USE_STRONG_CRYPTO is not available in VS2010 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa379810.aspx */ #ifdef SCH_USE_STRONG_CRYPTO schannel_cred.dwFlags = SCH_USE_STRONG_CRYPTO; #endif if (opt->weak_cert_validation) { schannel_cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE; TRACE ("disabled server certificate checks"); } else { schannel_cred.dwFlags |= SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_REVOCATION_CHECK_CHAIN; TRACE ("enabled server certificate checks"); } if (opt->allow_invalid_hostname) { schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK | SCH_CRED_IGNORE_NO_REVOCATION_CHECK; } if (opt->ca_file) { mongoc_secure_channel_setup_ca (secure_channel, opt); } if (opt->crl_file) { mongoc_secure_channel_setup_crl (secure_channel, opt); } if (opt->pem_file) { PCCERT_CONTEXT cert = mongoc_secure_channel_setup_certificate (secure_channel, opt); if (cert) { schannel_cred.cCreds = 1; schannel_cred.paCred = &cert; } } schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT; secure_channel->cred = (mongoc_secure_channel_cred *) bson_malloc0 ( sizeof (mongoc_secure_channel_cred)); /* Example: * https://msdn.microsoft.com/en-us/library/windows/desktop/aa375454%28v=vs.85%29.aspx * AcquireCredentialsHandle: * https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx */ sspi_status = AcquireCredentialsHandle ( NULL, /* principal */ UNISP_NAME, /* security package */ SECPKG_CRED_OUTBOUND, /* we are preparing outbound connection */ NULL, /* Optional logon */ &schannel_cred, /* TLS "configuration", "auth data" */ NULL, /* unused */ NULL, /* unused */ &secure_channel->cred->cred_handle, /* credential OUT param */ &secure_channel->cred->time_stamp); /* certificate expiration time */ if (sspi_status != SEC_E_OK) { LPTSTR msg = NULL; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError (), LANG_NEUTRAL, (LPTSTR) &msg, 0, NULL); MONGOC_ERROR ( "Failed to initialize security context, error code: 0x%04X%04X: '%s'", (sspi_status >> 16) & 0xffff, sspi_status & 0xffff, msg); LocalFree (msg); RETURN (NULL); } if (opt->ca_dir) { MONGOC_ERROR ("Setting mongoc_ssl_opt_t.ca_dir has no effect when built " "against Secure Channel"); } mongoc_counter_streams_active_inc (); RETURN ((mongoc_stream_t *) tls); } #endif /* MONGOC_ENABLE_SSL_SECURE_CHANNEL */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-channel.h0000664000175000017500000000241013210321137026221 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_CHANNEL_H #define MONGOC_STREAM_TLS_SECURE_CHANNEL_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_SECURE_CHANNEL #include #include "mongoc-macros.h" BSON_BEGIN_DECLS MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_tls_secure_channel_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client); BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_SECURE_CHANNEL */ #endif /* MONGOC_STREAM_TLS_SECURE_CHANNEL_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport-private.h0000664000175000017500000000242213210321137030320 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_TRANSPORT_PRIVATE_H #define MONGOC_STREAM_TLS_SECURE_TRANSPORT_PRIVATE_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT #include #include BSON_BEGIN_DECLS /** * mongoc_stream_tls_secure_transport_t: * * Private storage for Secure Transport Streams */ typedef struct { SSLContextRef ssl_ctx_ref; CFArrayRef anchors; CFMutableArrayRef my_cert; } mongoc_stream_tls_secure_transport_t; BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_SECURE_TRANSPORT */ #endif /* MONGOC_STREAM_TLS_SECURE_TRANSPORT_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.c0000664000175000017500000003713713210321137026656 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_TRANSPORT #include #include #include #include #include "mongoc-trace-private.h" #include "mongoc-log.h" #include "mongoc-secure-transport-private.h" #include "mongoc-ssl.h" #include "mongoc-error.h" #include "mongoc-counters-private.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-tls-private.h" #include "mongoc-stream-private.h" #include "mongoc-stream-tls-secure-transport-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-tls-secure_transport" static void _mongoc_stream_tls_secure_transport_destroy (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_transport); SSLClose (secure_transport->ssl_ctx_ref); CFRelease (secure_transport->ssl_ctx_ref); secure_transport->ssl_ctx_ref = NULL; /* SSLClose will do IO so destroy must come after */ mongoc_stream_destroy (tls->base_stream); if (secure_transport->anchors) { CFRelease (secure_transport->anchors); } if (secure_transport->my_cert) { CFRelease (secure_transport->my_cert); } bson_free (secure_transport); bson_free (stream); mongoc_counter_streams_active_dec (); mongoc_counter_streams_disposed_inc (); EXIT; } static void _mongoc_stream_tls_secure_transport_failed (mongoc_stream_t *stream) { ENTRY; _mongoc_stream_tls_secure_transport_destroy (stream); EXIT; } static int _mongoc_stream_tls_secure_transport_close (mongoc_stream_t *stream) { int ret = 0; mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_transport); ret = mongoc_stream_close (tls->base_stream); RETURN (ret); } static int _mongoc_stream_tls_secure_transport_flush (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_transport); RETURN (0); } static ssize_t _mongoc_stream_tls_secure_transport_write (mongoc_stream_t *stream, char *buf, size_t buf_len) { OSStatus status; mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ssize_t write_ret; int64_t now; int64_t expire = 0; ENTRY; BSON_ASSERT (secure_transport); if (tls->timeout_msec >= 0) { expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL); } status = SSLWrite ( secure_transport->ssl_ctx_ref, buf, buf_len, (size_t *) &write_ret); switch (status) { case errSSLWouldBlock: case noErr: break; case errSSLClosedAbort: errno = ECONNRESET; default: RETURN (-1); } if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { if (write_ret < buf_len) { mongoc_counter_streams_timeout_inc (); } tls->timeout_msec = 0; } else { tls->timeout_msec = (expire - now) / 1000L; } } RETURN (write_ret); } /* This is copypasta from _mongoc_stream_tls_openssl_writev */ #define MONGOC_STREAM_TLS_BUFFER_SIZE 4096 static ssize_t _mongoc_stream_tls_secure_transport_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; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; 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 (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (secure_transport); 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_secure_transport_write ( stream, to_write, to_write_len); if (child_ret < 0) { 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_secure_transport_write ( stream, 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); } TRACE ("Returning %zu", ret); RETURN (ret); } /* This function is copypasta of _mongoc_stream_tls_openssl_readv */ static ssize_t _mongoc_stream_tls_secure_transport_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; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ssize_t ret = 0; size_t i; size_t read_ret; size_t iov_pos = 0; int64_t now; int64_t expire = 0; BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (secure_transport); ENTRY; 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) { OSStatus status = SSLRead (secure_transport->ssl_ctx_ref, (char *) iov[i].iov_base + iov_pos, (int) (iov[i].iov_len - iov_pos), &read_ret); if (status != noErr) { RETURN (-1); } if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { if (read_ret == 0) { mongoc_counter_streams_timeout_inc (); errno = ETIMEDOUT; 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); } static int _mongoc_stream_tls_secure_transport_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, mongoc_socklen_t optlen) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_transport); RETURN (mongoc_stream_setsockopt ( tls->base_stream, level, optname, optval, optlen)); } static mongoc_stream_t * _mongoc_stream_tls_secure_transport_get_base_stream (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_transport); RETURN (tls->base_stream); } static bool _mongoc_stream_tls_secure_transport_check_closed ( mongoc_stream_t *stream) /* IN */ { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_transport); RETURN (mongoc_stream_check_closed (tls->base_stream)); } bool mongoc_stream_tls_secure_transport_handshake (mongoc_stream_t *stream, const char *host, int *events, bson_error_t *error) { OSStatus ret = 0; mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; mongoc_stream_tls_secure_transport_t *secure_transport = (mongoc_stream_tls_secure_transport_t *) tls->ctx; ENTRY; BSON_ASSERT (secure_transport); ret = SSLHandshake (secure_transport->ssl_ctx_ref); /* Weak certificate validation requested, eg: none */ if (ret == errSSLServerAuthCompleted) { ret = errSSLWouldBlock; } if (ret == noErr) { RETURN (true); } if (ret == errSSLWouldBlock) { *events = POLLIN | POLLOUT; } else { *events = 0; bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake failed: %d", ret); } RETURN (false); } static bool _mongoc_stream_tls_secure_channel_timed_out (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *) stream; ENTRY; RETURN (mongoc_stream_timed_out (tls->base_stream)); } mongoc_stream_t * mongoc_stream_tls_secure_transport_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { mongoc_stream_tls_t *tls; mongoc_stream_tls_secure_transport_t *secure_transport; ENTRY; BSON_ASSERT (base_stream); BSON_ASSERT (opt); if (opt->ca_dir) { MONGOC_ERROR ("Setting mongoc_ssl_opt_t.ca_dir has no effect when built " "against Secure Transport"); RETURN (false); } if (opt->crl_file) { MONGOC_ERROR ( "Setting mongoc_ssl_opt_t.crl_file has no effect when built " "against Secure Transport"); RETURN (false); } secure_transport = (mongoc_stream_tls_secure_transport_t *) bson_malloc0 ( sizeof *secure_transport); tls = (mongoc_stream_tls_t *) bson_malloc0 (sizeof *tls); tls->parent.type = MONGOC_STREAM_TLS; tls->parent.destroy = _mongoc_stream_tls_secure_transport_destroy; tls->parent.failed = _mongoc_stream_tls_secure_transport_failed; tls->parent.close = _mongoc_stream_tls_secure_transport_close; tls->parent.flush = _mongoc_stream_tls_secure_transport_flush; tls->parent.writev = _mongoc_stream_tls_secure_transport_writev; tls->parent.readv = _mongoc_stream_tls_secure_transport_readv; tls->parent.setsockopt = _mongoc_stream_tls_secure_transport_setsockopt; tls->parent.get_base_stream = _mongoc_stream_tls_secure_transport_get_base_stream; tls->parent.check_closed = _mongoc_stream_tls_secure_transport_check_closed; tls->parent.timed_out = _mongoc_stream_tls_secure_channel_timed_out; memcpy (&tls->ssl_opts, opt, sizeof tls->ssl_opts); tls->handshake = mongoc_stream_tls_secure_transport_handshake; tls->ctx = (void *) secure_transport; tls->timeout_msec = -1; tls->base_stream = base_stream; secure_transport->ssl_ctx_ref = SSLCreateContext (kCFAllocatorDefault, client ? kSSLClientSide : kSSLServerSide, kSSLStreamType); SSLSetIOFuncs (secure_transport->ssl_ctx_ref, mongoc_secure_transport_read, mongoc_secure_transport_write); SSLSetProtocolVersionMin (secure_transport->ssl_ctx_ref, kTLSProtocol1); mongoc_secure_transport_setup_certificate (secure_transport, opt); mongoc_secure_transport_setup_ca (secure_transport, opt); if (client) { SSLSetSessionOption (secure_transport->ssl_ctx_ref, kSSLSessionOptionBreakOnServerAuth, opt->weak_cert_validation); } else if (!opt->allow_invalid_hostname) { /* used only in mock_server_t tests */ SSLSetClientSideAuthenticate (secure_transport->ssl_ctx_ref, kAlwaysAuthenticate); } if (!opt->allow_invalid_hostname) { SSLSetPeerDomainName (secure_transport->ssl_ctx_ref, host, strlen (host)); } SSLSetConnection (secure_transport->ssl_ctx_ref, tls); mongoc_counter_streams_active_inc (); RETURN ((mongoc_stream_t *) tls); } #endif /* MONGOC_ENABLE_SSL_SECURE_TRANSPORT */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls-secure-transport.h0000664000175000017500000000243213210321137026651 0ustar jmikolajmikola/* * Copyright 2016 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_SECURE_TRANSPORT_H #define MONGOC_STREAM_TLS_SECURE_TRANSPORT_H #if !defined(MONGOC_INSIDE) && !defined(MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifdef MONGOC_ENABLE_SSL_SECURE_TRANSPORT #include #include "mongoc-macros.h" BSON_BEGIN_DECLS MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_tls_secure_transport_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client); BSON_END_DECLS #endif /* MONGOC_ENABLE_SSL_SECURE_TRANSPORT */ #endif /* MONGOC_STREAM_TLS_SECURE_TRANSPORT_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls.c0000664000175000017500000001567013210321137023336 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 "mongoc-log.h" #include "mongoc-trace-private.h" #include "mongoc-error.h" #include "mongoc-stream-tls-private.h" #include "mongoc-stream-private.h" #if defined(MONGOC_ENABLE_SSL_OPENSSL) #include "mongoc-stream-tls-openssl.h" #include "mongoc-openssl-private.h" #elif defined(MONGOC_ENABLE_SSL_LIBRESSL) #include "mongoc-libressl-private.h" #include "mongoc-stream-tls-libressl.h" #elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) #include "mongoc-secure-transport-private.h" #include "mongoc-stream-tls-secure-transport.h" #elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) #include "mongoc-secure-channel-private.h" #include "mongoc-stream-tls-secure-channel.h" #endif #include "mongoc-stream-tls.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-tls" /** * mongoc_stream_tls_handshake: * * Performs TLS handshake dance */ bool mongoc_stream_tls_handshake (mongoc_stream_t *stream, const char *host, int32_t timeout_msec, int *events, bson_error_t *error) { mongoc_stream_tls_t *stream_tls = (mongoc_stream_tls_t *) mongoc_stream_get_tls_stream (stream); BSON_ASSERT (stream_tls); BSON_ASSERT (stream_tls->handshake); stream_tls->timeout_msec = timeout_msec; return stream_tls->handshake (stream, host, events, error); } bool mongoc_stream_tls_handshake_block (mongoc_stream_t *stream, const char *host, int32_t timeout_msec, bson_error_t *error) { int events; ssize_t ret = 0; mongoc_stream_poll_t poller; int64_t now; int64_t expire = 0; if (timeout_msec >= 0) { expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); } /* * error variables get re-used a lot. To prevent cross-contamination of error * messages, and still be able to provide a generic failure message when * mongoc_stream_tls_handshake fails without a specific reason, we need to * init * the error code to 0. */ if (error) { error->code = 0; } do { events = 0; if (mongoc_stream_tls_handshake ( stream, host, timeout_msec, &events, error)) { return true; } if (events) { poller.stream = stream; poller.events = events; poller.revents = 0; if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake timed out."); return false; } else { timeout_msec = (expire - now) / 1000L; } } ret = mongoc_stream_poll (&poller, 1, timeout_msec); } } while (events && ret > 0); if (error && !error->code) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "TLS handshake failed."); } return false; } /** * Deprecated. Was never supposed to be part of the public API. * See mongoc_stream_tls_handshake. */ bool mongoc_stream_tls_do_handshake (mongoc_stream_t *stream, int32_t timeout_msec) { mongoc_stream_tls_t *stream_tls = (mongoc_stream_tls_t *) mongoc_stream_get_tls_stream (stream); BSON_ASSERT (stream_tls); MONGOC_ERROR ("This function doesn't do anything. Please call " "mongoc_stream_tls_handshake()"); return false; } /** * Deprecated. Was never supposed to be part of the public API. * See mongoc_stream_tls_handshake. */ bool mongoc_stream_tls_check_cert (mongoc_stream_t *stream, const char *host) { mongoc_stream_tls_t *stream_tls = (mongoc_stream_tls_t *) mongoc_stream_get_tls_stream (stream); BSON_ASSERT (stream_tls); MONGOC_ERROR ("This function doesn't do anything. Please call " "mongoc_stream_tls_handshake()"); return false; } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_new_with_hostname -- * * Creates a new mongoc_stream_tls_t to communicate with a remote * server using a TLS stream. * * @host the hostname we are connected to and to verify the * server certificate against * * @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_with_hostname (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { BSON_ASSERT (base_stream); /* !client is only used for testing, * when the streams are pretending to be the server */ if (!client || opt->weak_cert_validation) { opt->allow_invalid_hostname = true; } #ifndef _WIN32 /* Silly check for Unix Domain Sockets */ if (!host || (host[0] == '/' && !access (host, F_OK))) { opt->allow_invalid_hostname = true; } #endif #if defined(MONGOC_ENABLE_SSL_OPENSSL) return mongoc_stream_tls_openssl_new (base_stream, host, opt, client); #elif defined(MONGOC_ENABLE_SSL_LIBRESSL) return mongoc_stream_tls_libressl_new (base_stream, host, opt, client); #elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) return mongoc_stream_tls_secure_transport_new ( base_stream, host, opt, client); #elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) return mongoc_stream_tls_secure_channel_new (base_stream, host, opt, client); #else #error "Don't know how to create TLS stream" #endif } mongoc_stream_t * mongoc_stream_tls_new (mongoc_stream_t *base_stream, mongoc_ssl_opt_t *opt, int client) { return mongoc_stream_tls_new_with_hostname (base_stream, NULL, opt, client); } #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream-tls.h0000664000175000017500000000442613210321137023340 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-macros.h" #include "mongoc-ssl.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef struct _mongoc_stream_tls_t mongoc_stream_tls_t; MONGOC_EXPORT (bool) mongoc_stream_tls_handshake (mongoc_stream_t *stream, const char *host, int32_t timeout_msec, int *events, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_stream_tls_handshake_block (mongoc_stream_t *stream, const char *host, int32_t timeout_msec, bson_error_t *error); MONGOC_EXPORT (bool) mongoc_stream_tls_do_handshake (mongoc_stream_t *stream, int32_t timeout_msec) BSON_GNUC_DEPRECATED_FOR (mongoc_stream_tls_handshake); MONGOC_EXPORT (bool) mongoc_stream_tls_check_cert (mongoc_stream_t *stream, const char *host) BSON_GNUC_DEPRECATED_FOR (mongoc_stream_tls_handshake); MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_tls_new_with_hostname (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client); MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_tls_new (mongoc_stream_t *base_stream, mongoc_ssl_opt_t *opt, int client) BSON_GNUC_DEPRECATED_FOR (mongoc_stream_tls_new_with_hostname); BSON_END_DECLS #endif /* MONGOC_STREAM_TLS_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-stream.c0000664000175000017500000002744413210321137022540 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-private.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, mongoc_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; } mongoc_stream_t * mongoc_stream_get_tls_stream (mongoc_stream_t *stream) /* IN */ { BSON_ASSERT (stream); for (; stream && stream->type != MONGOC_STREAM_TLS; 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_timed_out (mongoc_stream_t *stream) { ENTRY; BSON_ASSERT (stream); /* for e.g. a file stream there is no timed_out function */ RETURN (stream->timed_out && stream->timed_out (stream)); } 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.3.4/src/libmongoc/src/mongoc/mongoc-stream.h0000664000175000017500000000765713210321137022551 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-macros.h" #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, mongoc_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); bool (*timed_out) (mongoc_stream_t *stream); void *padding[4]; }; MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_get_base_stream (mongoc_stream_t *stream); MONGOC_EXPORT (mongoc_stream_t *) mongoc_stream_get_tls_stream (mongoc_stream_t *stream); MONGOC_EXPORT (int) mongoc_stream_close (mongoc_stream_t *stream); MONGOC_EXPORT (void) mongoc_stream_destroy (mongoc_stream_t *stream); MONGOC_EXPORT (void) mongoc_stream_failed (mongoc_stream_t *stream); MONGOC_EXPORT (int) mongoc_stream_flush (mongoc_stream_t *stream); MONGOC_EXPORT (ssize_t) mongoc_stream_writev (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec); MONGOC_EXPORT (ssize_t) mongoc_stream_write (mongoc_stream_t *stream, void *buf, size_t count, int32_t timeout_msec); MONGOC_EXPORT (ssize_t) mongoc_stream_readv (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec); MONGOC_EXPORT (ssize_t) mongoc_stream_read (mongoc_stream_t *stream, void *buf, size_t count, size_t min_bytes, int32_t timeout_msec); MONGOC_EXPORT (int) mongoc_stream_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, mongoc_socklen_t optlen); MONGOC_EXPORT (bool) mongoc_stream_check_closed (mongoc_stream_t *stream); MONGOC_EXPORT (bool) mongoc_stream_timed_out (mongoc_stream_t *stream); MONGOC_EXPORT (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.3.4/src/libmongoc/src/mongoc/mongoc-thread-private.h0000664000175000017500000001033313210321137024156 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_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-config.h" #include "mongoc-log.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; } static BSON_INLINE DWORD mongoc_thread_join (mongoc_thread_t thread) { DWORD ret = WaitForSingleObject (thread, INFINITE); if (!CloseHandle (thread)) { MONGOC_ERROR ("Couldn't close thread handle, error 0x%.8X", GetLastError ()); } return ret; } #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, (DWORD) 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.3.4/src/libmongoc/src/mongoc/mongoc-topology-description-apm-private.h0000664000175000017500000000363413210321137027665 0ustar jmikolajmikola/* * Copyright 2016 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_APM_PRIVATE_H #define MONGOC_TOPOLOGY_DESCRIPTION_APM_PRIVATE_H #include #include "mongoc-topology-description-private.h" /* Application Performance Monitoring for topology events, complies with the * SDAM Monitoring Spec: https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst */ void _mongoc_topology_description_monitor_server_opening ( const mongoc_topology_description_t *td, mongoc_server_description_t *sd); void _mongoc_topology_description_monitor_server_changed ( const mongoc_topology_description_t *td, const mongoc_server_description_t *prev_sd, const mongoc_server_description_t *new_sd); void _mongoc_topology_description_monitor_server_closed ( const mongoc_topology_description_t *td, const mongoc_server_description_t *sd); /* td is not const: we set its "opened" field here */ void _mongoc_topology_description_monitor_opening ( mongoc_topology_description_t *td); void _mongoc_topology_description_monitor_changed ( const mongoc_topology_description_t *prev_td, const mongoc_topology_description_t *new_td); void _mongoc_topology_description_monitor_closed ( const mongoc_topology_description_t *td); #endif /* MONGOC_TOPOLOGY_DESCRIPTION_APM_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-topology-description-apm.c0000664000175000017500000001150113210321137026200 0ustar jmikolajmikola/* * Copyright 2016 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-topology-description-apm-private.h" #include "mongoc-server-description-private.h" /* Application Performance Monitoring for topology events, complies with the * SDAM Monitoring Spec: https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst */ /* ServerOpeningEvent */ void _mongoc_topology_description_monitor_server_opening ( const mongoc_topology_description_t *td, mongoc_server_description_t *sd) { if (td->apm_callbacks.server_opening && !sd->opened) { mongoc_apm_server_opening_t event; bson_oid_copy (&td->topology_id, &event.topology_id); event.host = &sd->host; event.context = td->apm_context; sd->opened = true; td->apm_callbacks.server_opening (&event); } } /* ServerDescriptionChangedEvent */ void _mongoc_topology_description_monitor_server_changed ( const mongoc_topology_description_t *td, const mongoc_server_description_t *prev_sd, const mongoc_server_description_t *new_sd) { if (td->apm_callbacks.server_changed) { mongoc_apm_server_changed_t event; /* address is same in previous and new sd */ bson_oid_copy (&td->topology_id, &event.topology_id); event.host = &new_sd->host; event.previous_description = prev_sd; event.new_description = new_sd; event.context = td->apm_context; td->apm_callbacks.server_changed (&event); } } /* ServerClosedEvent */ void _mongoc_topology_description_monitor_server_closed ( const mongoc_topology_description_t *td, const mongoc_server_description_t *sd) { if (td->apm_callbacks.server_closed) { mongoc_apm_server_closed_t event; bson_oid_copy (&td->topology_id, &event.topology_id); event.host = &sd->host; event.context = td->apm_context; td->apm_callbacks.server_closed (&event); } } /* Send TopologyOpeningEvent when first called on this topology description. * td is not const: we set its "opened" field here */ void _mongoc_topology_description_monitor_opening (mongoc_topology_description_t *td) { mongoc_topology_description_t *prev_td = NULL; size_t i; mongoc_server_description_t *sd; if (td->opened) { return; } if (td->apm_callbacks.topology_changed) { /* prepare to call monitor_changed */ prev_td = bson_malloc0 (sizeof (mongoc_topology_description_t)); mongoc_topology_description_init ( prev_td, MONGOC_TOPOLOGY_UNKNOWN, td->heartbeat_msec); } td->opened = true; if (td->apm_callbacks.topology_opening) { mongoc_apm_topology_opening_t event; bson_oid_copy (&td->topology_id, &event.topology_id); event.context = td->apm_context; td->apm_callbacks.topology_opening (&event); } if (td->apm_callbacks.topology_changed) { /* send initial description-changed event */ _mongoc_topology_description_monitor_changed (prev_td, td); } for (i = 0; i < td->servers->items_len; i++) { sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, (int) i); _mongoc_topology_description_monitor_server_opening (td, sd); } if (prev_td) { mongoc_topology_description_destroy (prev_td); bson_free (prev_td); } } /* TopologyDescriptionChangedEvent */ void _mongoc_topology_description_monitor_changed ( const mongoc_topology_description_t *prev_td, const mongoc_topology_description_t *new_td) { if (new_td->apm_callbacks.topology_changed) { mongoc_apm_topology_changed_t event; /* callbacks, context, and id are the same in previous and new td */ bson_oid_copy (&new_td->topology_id, &event.topology_id); event.context = new_td->apm_context; event.previous_description = prev_td; event.new_description = new_td; new_td->apm_callbacks.topology_changed (&event); } } /* TopologyClosedEvent */ void _mongoc_topology_description_monitor_closed ( const mongoc_topology_description_t *td) { if (td->apm_callbacks.topology_closed) { mongoc_apm_topology_closed_t event; bson_oid_copy (&td->topology_id, &event.topology_id); event.context = td->apm_context; td->apm_callbacks.topology_closed (&event); } } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-topology-description-private.h0000664000175000017500000000731713210321137027114 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" #include "mongoc-array-private.h" #include "mongoc-topology-description.h" #include "mongoc-apm-private.h" 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; struct _mongoc_topology_description_t { bson_oid_t topology_id; bool opened; mongoc_topology_description_type_t type; int64_t heartbeat_msec; mongoc_set_t *servers; char *set_name; int64_t max_set_version; bson_oid_t max_election_id; bson_error_t compatibility_error; uint32_t max_server_id; bool stale; unsigned int rand_seed; mongoc_apm_callbacks_t apm_callbacks; void *apm_context; }; 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, int64_t heartbeat_msec); void _mongoc_topology_description_copy_to (const mongoc_topology_description_t *src, mongoc_topology_description_t *dst); void mongoc_topology_description_destroy ( mongoc_topology_description_t *description); void mongoc_topology_description_handle_ismaster ( mongoc_topology_description_t *topology, uint32_t server_id, const bson_t *reply, int64_t rtt_msec, const bson_error_t *error /* IN */); 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); int32_t mongoc_topology_description_lowest_max_wire_version ( const mongoc_topology_description_t *td); bool mongoc_topology_description_all_sds_have_write_date ( const mongoc_topology_description_t *td); bool _mongoc_topology_description_validate_max_staleness ( const mongoc_topology_description_t *td, int64_t max_staleness_seconds, 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, const bson_error_t *error /* IN */); bool mongoc_topology_description_add_server (mongoc_topology_description_t *topology, const char *server, uint32_t *id /* OUT */); #endif /* MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-topology-description.c0000664000175000017500000016761313210321137025445 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-apm-private.h" #include "mongoc-trace-private.h" #include "mongoc-util-private.h" #include "mongoc-read-prefs-private.h" #include "mongoc-set-private.h" #include "mongoc-client-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, int64_t heartbeat_msec) { 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)); bson_oid_init (&description->topology_id, NULL); description->opened = false; description->type = type; description->heartbeat_msec = heartbeat_msec; description->servers = mongoc_set_new (8, _mongoc_topology_server_dtor, NULL); description->set_name = NULL; description->max_set_version = MONGOC_NO_SET_VERSION; description->stale = true; description->rand_seed = (unsigned int) bson_get_monotonic_time (); EXIT; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_copy_to -- * * Deep-copy @src to an uninitialized topology description @dst. * @dst must not already point to any allocated resources. Clean * up with mongoc_topology_description_destroy. * * WARNING: @dst's rand_seed is not initialized. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void _mongoc_topology_description_copy_to (const mongoc_topology_description_t *src, mongoc_topology_description_t *dst) { size_t nitems; size_t i; mongoc_server_description_t *sd; uint32_t id; ENTRY; BSON_ASSERT (src); BSON_ASSERT (dst); bson_oid_copy (&src->topology_id, &dst->topology_id); dst->opened = src->opened; dst->type = src->type; dst->heartbeat_msec = src->heartbeat_msec; nitems = bson_next_power_of_two (src->servers->items_len); dst->servers = mongoc_set_new (nitems, _mongoc_topology_server_dtor, NULL); for (i = 0; i < src->servers->items_len; i++) { sd = mongoc_set_get_item_and_id (src->servers, (int) i, &id); mongoc_set_add ( dst->servers, id, mongoc_server_description_new_copy (sd)); } dst->set_name = bson_strdup (src->set_name); dst->max_set_version = src->max_set_version; memcpy (&dst->compatibility_error, &src->compatibility_error, sizeof (bson_error_t)); dst->max_server_id = src->max_server_id; dst->stale = src->stale; memcpy (&dst->apm_callbacks, &src->apm_callbacks, sizeof (mongoc_apm_callbacks_t)); dst->apm_context = src->apm_context; 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); } 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_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_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; /* primary's used in staleness calculation, even with mode SECONDARY */ if (server->type == MONGOC_SERVER_RS_PRIMARY) { data->primary = server; } if (_mongoc_topology_description_server_is_candidate ( server->type, data->read_mode, data->topology_type)) { if (server->type == MONGOC_SERVER_RS_PRIMARY) { 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; } else { TRACE ("Rejected [%s] [%s] for mode [%s]", mongoc_server_description_type (server), server->host.host_and_port, _mongoc_read_mode_as_str (data->read_mode)); } return true; } /* if any mongos are candidates, add them to the candidates array */ static void _mongoc_try_mode_secondary (mongoc_array_t *set, /* OUT */ mongoc_topology_description_t *topology, const mongoc_read_prefs_t *read_pref, size_t local_threshold_ms) { mongoc_read_prefs_t *secondary; secondary = mongoc_read_prefs_copy (read_pref); mongoc_read_prefs_set_mode (secondary, MONGOC_READ_SECONDARY); mongoc_topology_description_suitable_servers ( set, MONGOC_SS_READ, topology, secondary, local_threshold_ms); mongoc_read_prefs_destroy (secondary); } /* 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_lowest_max_wire_version -- * * The topology's max wire version. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * * Returns: * The minimum of all known servers' max wire versions, or INT32_MAX * if there are no known servers. * * Side effects: * None. * *------------------------------------------------------------------------- */ int32_t mongoc_topology_description_lowest_max_wire_version ( const mongoc_topology_description_t *td) { int i; int32_t ret = INT32_MAX; mongoc_server_description_t *sd; for (i = 0; (size_t) i < td->servers->items_len; i++) { sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i); if (sd->type != MONGOC_SERVER_UNKNOWN && sd->max_wire_version < ret) { ret = sd->max_wire_version; } } return ret; } /* *------------------------------------------------------------------------- * * mongoc_topology_description_all_sds_have_write_date -- * * Whether the primary and all secondaries' server descriptions have * last_write_date_ms. * * Side effects: * None. * *------------------------------------------------------------------------- */ bool mongoc_topology_description_all_sds_have_write_date ( const mongoc_topology_description_t *td) { int i; mongoc_server_description_t *sd; for (i = 0; (size_t) i < td->servers->items_len; i++) { sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, i); if (sd->last_write_date_ms <= 0 && (sd->type == MONGOC_SERVER_RS_PRIMARY || sd->type == MONGOC_SERVER_RS_SECONDARY)) { return false; } } return true; } /* *------------------------------------------------------------------------- * * _mongoc_topology_description_validate_max_staleness -- * * If the provided "maxStalenessSeconds" component of the read * preference is not valid for this topology, fill out @error and * return false. * * Side effects: * None. * *------------------------------------------------------------------------- */ bool _mongoc_topology_description_validate_max_staleness ( const mongoc_topology_description_t *td, int64_t max_staleness_seconds, bson_error_t *error) { mongoc_topology_description_type_t td_type; /* Server Selection Spec: A driver MUST raise an error if the TopologyType * is ReplicaSetWithPrimary or ReplicaSetNoPrimary and either of these * conditions is false: * * maxStalenessSeconds * 1000 >= heartbeatFrequencyMS + idleWritePeriodMS * maxStalenessSeconds >= smallestMaxStalenessSeconds */ td_type = td->type; if (td_type != MONGOC_TOPOLOGY_RS_WITH_PRIMARY && td_type != MONGOC_TOPOLOGY_RS_NO_PRIMARY) { return true; } if (max_staleness_seconds * 1000 < td->heartbeat_msec + MONGOC_IDLE_WRITE_PERIOD_MS) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "maxStalenessSeconds is set to %" PRId64 ", it must be at least heartbeatFrequencyMS (%" PRId64 ") + server's idle write period (%d seconds)", max_staleness_seconds, td->heartbeat_msec, MONGOC_IDLE_WRITE_PERIOD_MS / 1000); return false; } if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "maxStalenessSeconds is set to %" PRId64 ", it must be at least %d seconds", max_staleness_seconds, MONGOC_SMALLEST_MAX_STALENESS_SECONDS); return false; } return true; } /* *------------------------------------------------------------------------- * * mongoc_topology_description_suitable_servers -- * * Fill out an array of servers matching the read preference and * localThresholdMS. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * * 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); } else { TRACE ( "Rejected [%s] [%s] for read mode [%s] with topology type Single", mongoc_server_description_type (server), server->host.host_and_port, _mongoc_read_mode_as_str (read_mode)); } 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 (read_mode == MONGOC_READ_PRIMARY) { if (data.primary) { _mongoc_array_append_val (set, data.primary); } goto DONE; } if (read_mode == MONGOC_READ_PRIMARY_PREFERRED && data.primary) { _mongoc_array_append_val (set, data.primary); goto DONE; } if (read_mode == MONGOC_READ_SECONDARY_PREFERRED) { /* try read_mode SECONDARY */ _mongoc_try_mode_secondary ( set, topology, read_pref, local_threshold_ms); /* otherwise fall back to primary */ if (!set->len && data.primary) { _mongoc_array_append_val (set, data.primary); } goto DONE; } if (read_mode == MONGOC_READ_SECONDARY) { for (i = 0; i < data.candidates_len; i++) { if (candidates[i] && candidates[i]->type != MONGOC_SERVER_RS_SECONDARY) { TRACE ("Rejected [%s] [%s] for mode [%s] with RS topology", mongoc_server_description_type (candidates[i]), candidates[i]->host.host_and_port, _mongoc_read_mode_as_str (read_mode)); candidates[i] = NULL; } } } /* mode is SECONDARY or NEAREST, filter by staleness and tags */ mongoc_server_description_filter_stale (data.candidates, data.candidates_len, data.primary, topology->heartbeat_msec, read_pref); mongoc_server_description_filter_tags ( data.candidates, data.candidates_len, read_pref); } 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_msec)) { nearest = candidates[i]->round_trip_time_msec; } } for (i = 0; i < data.candidates_len; i++) { if (candidates[i] && (candidates[i]->round_trip_time_msec <= 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; int rand_n; ENTRY; 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 { TRACE ("Topology type single, [%s] is down", sd->host.host_and_port); 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) { rand_n = _mongoc_rand_simple (&topology->rand_seed); sd = _mongoc_array_index (&suitable_servers, mongoc_server_description_t *, rand_n % suitable_servers.len); } _mongoc_array_destroy (&suitable_servers); if (sd) { TRACE ("Topology type [%s], selected [%s] [%s]", mongoc_topology_description_type (topology), mongoc_server_description_type (sd), sd->host.host_and_port); } 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_topology_description_monitor_server_closed (description, 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, the error is recorded, and other parameters are reset to * defaults. Pass in the reason for invalidation in @error. * * 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, const bson_error_t *error /* IN */) { BSON_ASSERT (error); /* send NULL ismaster reply */ mongoc_topology_description_handle_ismaster (topology, id, NULL, 0, error); } /* *-------------------------------------------------------------------------- * * 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 we're in topology_new then no callbacks are registered and this is * a no-op. later, if we discover a new RS member this sends an event. */ _mongoc_topology_description_monitor_server_opening (topology, 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_error_t error; 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)) { bson_set_error (&error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "member's setVersion or electionId is stale"); mongoc_topology_description_invalidate_server ( topology, server->id, &error); _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}}; #ifdef MONGOC_TRACE /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_type -- * * Get this topology's type, one of the types defined in the Server * Discovery And Monitoring Spec. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * * Returns: * A string. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static const char * _mongoc_topology_description_type (mongoc_topology_description_t *topology) { switch (topology->type) { case MONGOC_TOPOLOGY_UNKNOWN: return "Unknown"; case MONGOC_TOPOLOGY_SHARDED: return "Sharded"; case MONGOC_TOPOLOGY_RS_NO_PRIMARY: return "RSNoPrimary"; case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: return "RSWithPrimary"; case MONGOC_TOPOLOGY_SINGLE: return "Single"; case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: default: MONGOC_ERROR ("Invalid mongoc_topology_description_type_t type"); return "Invalid"; } } #endif /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_check_compatible -- * * Fill out td.compatibility_error if any server's wire versions do * not overlap with ours. Otherwise clear td.compatibility_error. * * If any server is incompatible, the topology as a whole is considered * incompatible. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_check_compatible ( mongoc_topology_description_t *td) { size_t i; mongoc_server_description_t *sd; bool server_too_new; bool server_too_old; memset (&td->compatibility_error, 0, sizeof (bson_error_t)); for (i = 0; i < td->servers->items_len; i++) { sd = (mongoc_server_description_t *) mongoc_set_get_item (td->servers, (int) i); if (sd->type == MONGOC_SERVER_UNKNOWN || sd->type == MONGOC_SERVER_POSSIBLE_PRIMARY) { continue; } /* A server is considered to be incompatible with a driver if its min and * max wire version does not overlap the driver’s. Specifically, a driver * with a min and max range of [a, b] must be considered incompatible * with any server with min and max range of [c, d] where c > b or d < a. * All other servers are considered to be compatible. */ server_too_new = sd->min_wire_version > WIRE_VERSION_MAX; server_too_old = sd->max_wire_version < WIRE_VERSION_MIN; if (server_too_new || server_too_old) { bson_set_error (&td->compatibility_error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "Server at \"%s\" uses wire protocol versions %d" " through %d, but libmongoc %s only supports %d" " through %d", sd->host.host_and_port, sd->min_wire_version, sd->max_wire_version, MONGOC_VERSION_S, WIRE_VERSION_MIN, WIRE_VERSION_MAX); break; } } } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_handle_ismaster -- * * Handle an ismaster. This is called by the background SDAM process, * and by client when invalidating servers. If there was an error * calling ismaster, pass it in as @error. * * 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, uint32_t server_id, const bson_t *ismaster_response, int64_t rtt_msec, const bson_error_t *error /* IN */) { mongoc_topology_description_t *prev_td = NULL; mongoc_server_description_t *prev_sd = NULL; mongoc_server_description_t *sd; BSON_ASSERT (topology); BSON_ASSERT (server_id != 0); sd = mongoc_topology_description_server_by_id (topology, server_id, NULL); if (!sd) { return; /* server already removed from topology */ } if (topology->apm_callbacks.topology_changed) { prev_td = bson_malloc0 (sizeof (mongoc_topology_description_t)); _mongoc_topology_description_copy_to (topology, prev_td); } if (topology->apm_callbacks.server_changed) { prev_sd = mongoc_server_description_new_copy (sd); } /* pass the current error in */ mongoc_server_description_handle_ismaster ( sd, ismaster_response, rtt_msec, error); _mongoc_topology_description_monitor_server_changed (topology, prev_sd, sd); if (gSDAMTransitionTable[sd->type][topology->type]) { TRACE ("Transitioning to %s for %s", _mongoc_topology_description_type (topology), mongoc_server_description_type (sd)); gSDAMTransitionTable[sd->type][topology->type](topology, sd); } else { TRACE ("No transition entry to %s for %s", _mongoc_topology_description_type (topology), mongoc_server_description_type (sd)); } _mongoc_topology_description_check_compatible (topology); _mongoc_topology_description_monitor_changed (prev_td, topology); if (prev_td) { mongoc_topology_description_destroy (prev_td); bson_free (prev_td); } if (prev_sd) { mongoc_server_description_destroy (prev_sd); } } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_has_readable_server -- * * SDAM Monitoring Spec: * "Determines if the topology has a readable server available." * * NOTE: this method should only be called by user code in an SDAM * Monitoring callback, while the monitoring framework holds the mutex * on the owning topology object. * *-------------------------------------------------------------------------- */ bool mongoc_topology_description_has_readable_server ( mongoc_topology_description_t *td, const mongoc_read_prefs_t *prefs) { bson_error_t error; if (!mongoc_topology_compatible (td, NULL, &error)) { return false; } /* local threshold argument doesn't matter */ return mongoc_topology_description_select (td, MONGOC_SS_READ, prefs, 0) != NULL; } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_has_writable_server -- * * SDAM Monitoring Spec: * "Determines if the topology has a writable server available." * * NOTE: this method should only be called by user code in an SDAM * Monitoring callback, while the monitoring framework holds the mutex * on the owning topology object. * *-------------------------------------------------------------------------- */ bool mongoc_topology_description_has_writable_server ( mongoc_topology_description_t *td) { bson_error_t error; if (!mongoc_topology_compatible (td, NULL, &error)) { return false; } return mongoc_topology_description_select (td, MONGOC_SS_WRITE, NULL, 0) != NULL; } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_type -- * * Get this topology's type, one of the types defined in the Server * Discovery And Monitoring Spec. * * NOTE: this method should only be called by user code in an SDAM * Monitoring callback, while the monitoring framework holds the mutex * on the owning topology object. * * Returns: * A string. * *-------------------------------------------------------------------------- */ const char * mongoc_topology_description_type (const mongoc_topology_description_t *td) { switch (td->type) { case MONGOC_TOPOLOGY_UNKNOWN: return "Unknown"; case MONGOC_TOPOLOGY_SHARDED: return "Sharded"; case MONGOC_TOPOLOGY_RS_NO_PRIMARY: return "ReplicaSetNoPrimary"; case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: return "ReplicaSetWithPrimary"; case MONGOC_TOPOLOGY_SINGLE: return "Single"; case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: default: fprintf (stderr, "ERROR: Unknown topology type %d\n", td->type); BSON_ASSERT (0); } return NULL; } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_get_servers -- * * Fetch an array of server descriptions for all known servers in the * topology. * * Returns: * An array you must free with mongoc_server_descriptions_destroy_all. * *-------------------------------------------------------------------------- */ mongoc_server_description_t ** mongoc_topology_description_get_servers ( const mongoc_topology_description_t *td, size_t *n /* OUT */) { size_t i; mongoc_set_t *set; mongoc_server_description_t **sds; mongoc_server_description_t *sd; BSON_ASSERT (td); BSON_ASSERT (n); set = td->servers; /* enough room for all descriptions, even if some are unknown */ sds = (mongoc_server_description_t **) bson_malloc0 ( sizeof (mongoc_server_description_t *) * set->items_len); *n = 0; for (i = 0; i < set->items_len; ++i) { sd = (mongoc_server_description_t *) mongoc_set_get_item (set, (int) i); if (sd->type != MONGOC_SERVER_UNKNOWN) { sds[*n] = mongoc_server_description_new_copy (sd); ++(*n); } } return sds; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-topology-description.h0000664000175000017500000000260413210321137025436 0ustar jmikolajmikola/* * Copyright 2016 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_H #define MONGOC_TOPOLOGY_DESCRIPTION_H #include #include "mongoc-macros.h" #include "mongoc-read-prefs.h" BSON_BEGIN_DECLS typedef struct _mongoc_topology_description_t mongoc_topology_description_t; MONGOC_EXPORT (bool) mongoc_topology_description_has_readable_server ( mongoc_topology_description_t *td, const mongoc_read_prefs_t *prefs); MONGOC_EXPORT (bool) mongoc_topology_description_has_writable_server ( mongoc_topology_description_t *td); MONGOC_EXPORT (const char *) mongoc_topology_description_type (const mongoc_topology_description_t *td); MONGOC_EXPORT (mongoc_server_description_t **) mongoc_topology_description_get_servers ( const mongoc_topology_description_t *td, size_t *n); BSON_END_DECLS #endif /* MONGOC_TOPOLOGY_DESCRIPTION_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-topology-private.h0000664000175000017500000001012213210321137024557 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_LOCAL_THRESHOLD_MS 15 #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_SCANNER_OFF, MONGOC_TOPOLOGY_SCANNER_BG_RUNNING, MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN, MONGOC_TOPOLOGY_SCANNER_SINGLE_THREADED, } mongoc_topology_scanner_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 local_threshold_msec; int64_t connect_timeout_msec; int64_t server_selection_timeout_msec; mongoc_mutex_t mutex; mongoc_cond_t cond_client; mongoc_cond_t cond_server; mongoc_thread_t thread; mongoc_topology_scanner_state_t scanner_state; bool scan_requested; 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_set_apm_callbacks (mongoc_topology_t *topology, mongoc_apm_callbacks_t *callbacks, void *context); void mongoc_topology_destroy (mongoc_topology_t *topology); bool mongoc_topology_compatible (const mongoc_topology_description_t *td, const mongoc_read_prefs_t *read_prefs, bson_error_t *error); mongoc_server_description_t * mongoc_topology_select (mongoc_topology_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, bson_error_t *error); uint32_t mongoc_topology_select_server_id (mongoc_topology_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, bson_error_t *error); mongoc_server_description_t * mongoc_topology_server_by_id (mongoc_topology_t *topology, uint32_t id, bson_error_t *error); mongoc_host_list_t * _mongoc_topology_host_by_id (mongoc_topology_t *topology, uint32_t id, bson_error_t *error); void mongoc_topology_invalidate_server (mongoc_topology_t *topology, uint32_t id, const bson_error_t *error); bool _mongoc_topology_update_from_handshake (mongoc_topology_t *topology, const mongoc_server_description_t *sd); int64_t mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id); mongoc_topology_description_type_t _mongoc_topology_get_type (mongoc_topology_t *topology); bool _mongoc_topology_start_background_scanner (mongoc_topology_t *topology); bool _mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname); #endif mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h0000664000175000017500000001172113210321137026214 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_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" #include "mongoc-apm-private.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-ssl.h" #endif BSON_BEGIN_DECLS typedef void (*mongoc_topology_scanner_setup_err_cb_t) ( uint32_t id, void *data, const bson_error_t *error /* IN */); typedef void (*mongoc_topology_scanner_cb_t) ( uint32_t id, const bson_t *bson, int64_t rtt, void *data, const bson_error_t *error /* IN */); 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; bson_t ismaster_cmd; bson_t ismaster_cmd_with_handshake; bool handshake_ok_to_send; const char *appname; mongoc_topology_scanner_setup_err_cb_t setup_err_cb; 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; bson_error_t error; #ifdef MONGOC_ENABLE_SSL mongoc_ssl_opt_t *ssl_opts; #endif mongoc_apm_callbacks_t apm_callbacks; void *apm_context; } mongoc_topology_scanner_t; mongoc_topology_scanner_t * mongoc_topology_scanner_new ( const mongoc_uri_t *uri, mongoc_topology_scanner_setup_err_cb_t setup_err_cb, mongoc_topology_scanner_cb_t cb, void *data); void mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts); void mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, uint32_t id); void mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, 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, int64_t timeout_msec, bool obey_cooldown); void mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts); void _mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts); void mongoc_topology_scanner_get_error (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); bson_t * _mongoc_topology_scanner_get_ismaster (mongoc_topology_scanner_t *ts); 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); bool _mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts, const char *name); #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.3.4/src/libmongoc/src/mongoc/mongoc-topology-scanner.c0000664000175000017500000005557413210321137024555 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-config.h" #include "mongoc-error.h" #include "mongoc-trace-private.h" #include "mongoc-topology-scanner-private.h" #include "mongoc-stream-socket.h" #include "mongoc-handshake.h" #include "mongoc-handshake-private.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" /* forward declarations */ 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); static void _mongoc_topology_scanner_monitor_heartbeat_started ( const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host); static void _mongoc_topology_scanner_monitor_heartbeat_succeeded ( const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, const bson_t *reply); static void _mongoc_topology_scanner_monitor_heartbeat_failed ( const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, const bson_error_t *error); static void _add_ismaster (bson_t *cmd) { BSON_APPEND_INT32 (cmd, "isMaster", 1); } static bool _build_ismaster_with_handshake (mongoc_topology_scanner_t *ts) { bson_t *doc = &ts->ismaster_cmd_with_handshake; bson_t subdoc; bson_iter_t iter; const char *key; int keylen; bool res; const bson_t *compressors; int count = 0; char buf[16]; _add_ismaster (doc); BSON_APPEND_DOCUMENT_BEGIN (doc, HANDSHAKE_FIELD, &subdoc); res = _mongoc_handshake_build_doc_with_application (&subdoc, ts->appname); bson_append_document_end (doc, &subdoc); BSON_APPEND_ARRAY_BEGIN (doc, "compression", &subdoc); if (ts->uri) { compressors = mongoc_uri_get_compressors (ts->uri); if (bson_iter_init (&iter, compressors)) { while (bson_iter_next (&iter)) { keylen = bson_uint32_to_string (count++, &key, buf, sizeof buf); bson_append_utf8 ( &subdoc, key, (int) keylen, bson_iter_key (&iter), -1); } } } bson_append_array_end (doc, &subdoc); /* Return whether the handshake doc fit the size limit */ return res; } bson_t * _mongoc_topology_scanner_get_ismaster (mongoc_topology_scanner_t *ts) { /* If this is the first time using the node or if it's the first time * using it after a failure, build handshake doc */ if (bson_empty (&ts->ismaster_cmd_with_handshake)) { ts->handshake_ok_to_send = _build_ismaster_with_handshake (ts); if (!ts->handshake_ok_to_send) { MONGOC_WARNING ("Handshake doc too big, not including in isMaster"); } } /* If the doc turned out to be too big */ if (!ts->handshake_ok_to_send) { return &ts->ismaster_cmd; } return &ts->ismaster_cmd_with_handshake; } static void _begin_ismaster_cmd (mongoc_topology_scanner_t *ts, mongoc_topology_scanner_node_t *node, int64_t timeout_msec) { const bson_t *command; if (node->last_used != -1 && node->last_failed == -1) { /* The node's been used before and not failed recently */ command = &ts->ismaster_cmd; } else { command = _mongoc_topology_scanner_get_ismaster (ts); } node->cmd = mongoc_async_cmd_new (ts->async, node->stream, ts->setup, node->host.host, "admin", command, &mongoc_topology_scanner_ismaster_handler, node, timeout_msec); } mongoc_topology_scanner_t * mongoc_topology_scanner_new ( const mongoc_uri_t *uri, mongoc_topology_scanner_setup_err_cb_t setup_err_cb, 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); _add_ismaster (&ts->ismaster_cmd); bson_init (&ts->ismaster_cmd_with_handshake); ts->setup_err_cb = setup_err_cb; ts->cb = cb; ts->cb_data = data; ts->uri = uri; ts->appname = NULL; ts->handshake_ok_to_send = false; 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_destroy (&ts->ismaster_cmd_with_handshake); /* This field can be set by a mongoc_client */ bson_free ((char *) ts->appname); bson_free (ts); } void 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; node->last_used = -1; DL_APPEND (ts->nodes, node); } void mongoc_topology_scanner_scan (mongoc_topology_scanner_t *ts, uint32_t id, int64_t timeout_msec) { mongoc_topology_scanner_node_t *node; BSON_ASSERT (timeout_msec < INT32_MAX); node = mongoc_topology_scanner_get_node (ts, id); /* begin non-blocking connection, don't wait for success */ if (node && mongoc_topology_scanner_node_setup (node, &node->last_error)) { _begin_ismaster_cmd (ts, node, timeout_msec); } /* if setup fails the node stays in the scanner. destroyed after the scan. */ } 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. * *-------------------------------------------------------------------------- */ 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; mongoc_topology_scanner_t *ts; int64_t now; const char *message; BSON_ASSERT (data); node = (mongoc_topology_scanner_node_t *) data; ts = node->ts; 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; if (error->code) { message = error->message; } else { if (async_status == MONGOC_ASYNC_CMD_TIMEOUT) { message = "connection timeout"; } else { message = "connection error"; } } bson_set_error (&node->last_error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_STREAM_CONNECT, "%s calling ismaster on \'%s\'", message, node->host.host_and_port); _mongoc_topology_scanner_monitor_heartbeat_failed ( ts, &node->host, &node->last_error); } else { node->last_failed = -1; _mongoc_topology_scanner_monitor_heartbeat_succeeded ( ts, &node->host, ismaster_response); } node->last_used = now; ts->cb (node->id, ismaster_response, rtt_msec, 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, (mongoc_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; _mongoc_topology_scanner_monitor_heartbeat_started (node->ts, &node->host); 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) { mongoc_stream_t *original = sock_stream; sock_stream = mongoc_stream_tls_new_with_hostname ( sock_stream, node->host.host, node->ts->ssl_opts, 1); if (!sock_stream) { mongoc_stream_destroy (original); } } #endif } if (!sock_stream) { _mongoc_topology_scanner_monitor_heartbeat_failed ( node->ts, &node->host, error); node->ts->setup_err_cb (node->id, 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, int64_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); _begin_ismaster_cmd (ts, node, timeout_msec); } } } } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_finish_scan -- * * Summarizes all scanner node errors into one error message. * *-------------------------------------------------------------------------- */ void _mongoc_topology_scanner_finish (mongoc_topology_scanner_t *ts) { mongoc_topology_scanner_node_t *node, *tmp; bson_error_t *error = &ts->error; bson_string_t *msg; memset (&ts->error, 0, sizeof (bson_error_t)); msg = bson_string_new (NULL); DL_FOREACH_SAFE (ts->nodes, node, tmp) { if (node->last_error.code) { if (msg->len) { bson_string_append_c (msg, ' '); } bson_string_append_printf (msg, "[%s]", node->last_error.message); /* last error domain and code win */ error->domain = node->last_error.domain; error->code = node->last_error.code; } } bson_strncpy ((char *) &error->message, msg->str, sizeof (error->message)); bson_string_free (msg, true); } /* *-------------------------------------------------------------------------- * * 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. * *-------------------------------------------------------------------------- */ void mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts) { mongoc_async_run (ts->async); } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_get_error -- * * Copy the scanner's current error; which may no-error (code 0). * *-------------------------------------------------------------------------- */ void mongoc_topology_scanner_get_error (mongoc_topology_scanner_t *ts, bson_error_t *error) { BSON_ASSERT (ts); BSON_ASSERT (error); memcpy (error, &ts->error, sizeof (bson_error_t)); } /* *-------------------------------------------------------------------------- * * 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); } } } /* * Set a field in the topology scanner. */ bool _mongoc_topology_scanner_set_appname (mongoc_topology_scanner_t *ts, const char *appname) { if (!_mongoc_handshake_appname_is_valid (appname)) { MONGOC_ERROR ("Cannot set appname: %s is invalid", appname); return false; } if (ts->appname != NULL) { MONGOC_ERROR ("Cannot set appname more than once"); return false; } ts->appname = bson_strdup (appname); return true; } /* SDAM Monitoring Spec: send HeartbeatStartedEvent */ static void _mongoc_topology_scanner_monitor_heartbeat_started ( const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host) { if (ts->apm_callbacks.server_heartbeat_started) { mongoc_apm_server_heartbeat_started_t event; event.host = host; event.context = ts->apm_context; ts->apm_callbacks.server_heartbeat_started (&event); } } /* SDAM Monitoring Spec: send HeartbeatSucceededEvent */ static void _mongoc_topology_scanner_monitor_heartbeat_succeeded ( const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, const bson_t *reply) { if (ts->apm_callbacks.server_heartbeat_succeeded) { mongoc_apm_server_heartbeat_succeeded_t event; event.host = host; event.context = ts->apm_context; event.reply = reply; ts->apm_callbacks.server_heartbeat_succeeded (&event); } } /* SDAM Monitoring Spec: send HeartbeatFailedEvent */ static void _mongoc_topology_scanner_monitor_heartbeat_failed ( const mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, const bson_error_t *error) { if (ts->apm_callbacks.server_heartbeat_failed) { mongoc_apm_server_heartbeat_failed_t event; event.host = host; event.context = ts->apm_context; event.error = error; ts->apm_callbacks.server_heartbeat_failed (&event); } } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-topology.c0000664000175000017500000010605213210321137023112 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" #include "mongoc-handshake.h" #include "mongoc-handshake-private.h" #include "mongoc-error.h" #include "mongoc-log.h" #include "mongoc-topology-private.h" #include "mongoc-topology-description-apm-private.h" #include "mongoc-client-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_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 (scanner, &sd->host, sd->id); mongoc_topology_scanner_scan ( scanner, 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); } } } /* call this while already holding the lock */ static bool _mongoc_topology_update_no_lock (uint32_t id, const bson_t *ismaster_response, int64_t rtt_msec, mongoc_topology_t *topology, const bson_error_t *error /* IN */) { mongoc_topology_description_handle_ismaster ( &topology->description, id, 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); /* return false if server removed from topology */ return mongoc_topology_description_server_by_id ( &topology->description, id, NULL) != NULL; } /* *------------------------------------------------------------------------- * * _mongoc_topology_scanner_setup_err_cb -- * * Callback method to handle errors during topology scanner node * setup, typically DNS or SSL errors. * *------------------------------------------------------------------------- */ void _mongoc_topology_scanner_setup_err_cb (uint32_t id, void *data, const bson_error_t *error /* IN */) { mongoc_topology_t *topology; BSON_ASSERT (data); topology = (mongoc_topology_t *) data; mongoc_topology_description_handle_ismaster (&topology->description, id, NULL /* ismaster reply */, -1 /* rtt_msec */, error); } /* *------------------------------------------------------------------------- * * _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, const bson_error_t *error /* IN */) { mongoc_topology_t *topology; mongoc_server_description_t *sd; BSON_ASSERT (data); topology = (mongoc_topology_t *) data; mongoc_mutex_lock (&topology->mutex); sd = mongoc_topology_description_server_by_id ( &topology->description, id, NULL); /* Server Discovery and Monitoring Spec: "Once a server is connected, the * client MUST change its type to Unknown only after it has retried the * server once." */ if (!ismaster_response && sd && sd->type != MONGOC_SERVER_UNKNOWN) { _mongoc_topology_update_no_lock ( id, ismaster_response, rtt_msec, topology, error); /* add another ismaster call to the current scan - the scan continues * until all commands are done */ mongoc_topology_scanner_scan ( topology->scanner, sd->id, topology->connect_timeout_msec); } else { _mongoc_topology_update_no_lock ( id, ismaster_response, rtt_msec, topology, error); mongoc_cond_broadcast (&topology->cond_client); } 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) { int64_t heartbeat_default; int64_t heartbeat; 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; } } heartbeat_default = single_threaded ? MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED : MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED; heartbeat = mongoc_uri_get_option_as_int32 ( uri, MONGOC_URI_HEARTBEATFREQUENCYMS, heartbeat_default); mongoc_topology_description_init ( &topology->description, init_type, heartbeat); topology->description.set_name = bson_strdup (mongoc_uri_get_replica_set (uri)); topology->uri = mongoc_uri_copy (uri); topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_OFF; topology->scanner = mongoc_topology_scanner_new (topology->uri, _mongoc_topology_scanner_setup_err_cb, _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, MONGOC_URI_SERVERSELECTIONTRYONCE, true); } else { topology->server_selection_try_once = false; } topology->server_selection_timeout_msec = mongoc_uri_get_option_as_int32 ( topology->uri, MONGOC_URI_SERVERSELECTIONTIMEOUTMS, MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS); topology->local_threshold_msec = mongoc_uri_get_local_threshold_option (topology->uri); /* 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, MONGOC_URI_CONNECTTIMEOUTMS, MONGOC_DEFAULT_CONNECTTIMEOUTMS); 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); } return topology; } /* *------------------------------------------------------------------------- * * mongoc_topology_set_apm_callbacks -- * * Set Application Performance Monitoring callbacks. * *------------------------------------------------------------------------- */ void mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology, mongoc_apm_callbacks_t *callbacks, void *context) { if (callbacks) { memcpy (&topology->description.apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); memcpy (&topology->scanner->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t)); } topology->description.apm_context = context; topology->scanner->apm_context = context; } /* *------------------------------------------------------------------------- * * 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_topology_description_monitor_closed (&topology->description); 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_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_t *scanner; topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_SINGLE_THREADED; _mongoc_handshake_freeze (); scanner = topology->scanner; mongoc_topology_scanner_start ( scanner, (int32_t) topology->connect_timeout_msec, true); mongoc_topology_scanner_work (topology->scanner); mongoc_mutex_lock (&topology->mutex); _mongoc_topology_scanner_finish (scanner); mongoc_topology_scanner_get_error (scanner, error); /* "retired" nodes can be checked again in the next scan */ mongoc_topology_scanner_reset (scanner); topology->last_scan = bson_get_monotonic_time (); topology->stale = false; mongoc_mutex_unlock (&topology->mutex); } bool mongoc_topology_compatible (const mongoc_topology_description_t *td, const mongoc_read_prefs_t *read_prefs, bson_error_t *error) { int64_t max_staleness_seconds; int32_t max_wire_version; if (td->compatibility_error.code) { memcpy (error, &td->compatibility_error, sizeof (bson_error_t)); return false; } if (!read_prefs) { /* NULL means read preference Primary */ return true; } max_staleness_seconds = mongoc_read_prefs_get_max_staleness_seconds (read_prefs); if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { max_wire_version = mongoc_topology_description_lowest_max_wire_version (td); if (max_wire_version < WIRE_VERSION_MAX_STALENESS) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "Not all servers support maxStalenessSeconds"); return false; } /* shouldn't happen if we've properly enforced wire version */ if (!mongoc_topology_description_all_sds_have_write_date (td)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "Not all servers have lastWriteDate"); return false; } if (!_mongoc_topology_description_validate_max_staleness ( td, max_staleness_seconds, error)) { return false; } } return true; } static void _mongoc_server_selection_error (const char *msg, const bson_error_t *scanner_error, bson_error_t *error) { if (scanner_error && scanner_error->code) { bson_set_error (error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "%s: %s", msg, scanner_error->message); } else { bson_set_error (error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "%s", msg); } } /* *------------------------------------------------------------------------- * * 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. * @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, bson_error_t *error) { uint32_t server_id = mongoc_topology_select_server_id (topology, optype, read_prefs, error); if (server_id) { /* new copy of the server description */ return mongoc_topology_server_by_id (topology, server_id, error); } else { return NULL; } } /* *------------------------------------------------------------------------- * * mongoc_topology_select_server_id -- * * Alternative to mongoc_topology_select when you only need the id. * * Returns: * A server id, or 0 on failure, in which case @error will be set. * *------------------------------------------------------------------------- */ uint32_t mongoc_topology_select_server_id (mongoc_topology_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, bson_error_t *error) { static const char *timeout_msg = "No suitable servers found: `serverSelectionTimeoutMS` expired"; int r; int64_t local_threshold_ms; mongoc_server_description_t *selected_server = NULL; bool try_once; int64_t sleep_usec; bool tried_once; bson_error_t scanner_error = {0}; int64_t heartbeat_msec; uint32_t server_id; /* 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); heartbeat_msec = topology->description.heartbeat_msec; local_threshold_ms = topology->local_threshold_msec; 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) { _mongoc_topology_description_monitor_opening (&topology->description); tried_once = false; next_update = topology->last_scan + 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 */ _mongoc_server_selection_error ( "No suitable servers found: " "`serverselectiontimeoutms` timed out", &scanner_error, error); topology->stale = true; return 0; } 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); loop_end = topology->last_scan; tried_once = true; } if (!mongoc_topology_compatible ( &topology->description, read_prefs, error)) { return 0; } selected_server = mongoc_topology_description_select ( &topology->description, optype, read_prefs, local_threshold_ms); if (selected_server) { return selected_server->id; } topology->stale = true; if (try_once) { if (tried_once) { _mongoc_server_selection_error ( "No suitable servers found (`serverSelectionTryOnce` set)", &scanner_error, error); return 0; } } else { loop_end = bson_get_monotonic_time (); if (loop_end > expire_at) { /* no time left in server_selection_timeout_msec */ _mongoc_server_selection_error ( timeout_msg, &scanner_error, error); return 0; } } } } /* With background thread */ /* we break out when we've found a server or timed out */ for (;;) { mongoc_mutex_lock (&topology->mutex); if (!mongoc_topology_compatible ( &topology->description, read_prefs, error)) { mongoc_mutex_unlock (&topology->mutex); return 0; } 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_topology_scanner_get_error (topology->scanner, &scanner_error); mongoc_mutex_unlock (&topology->mutex); #ifdef _WIN32 if (r == WSAETIMEDOUT) { #else if (r == ETIMEDOUT) { #endif /* handle timeouts */ _mongoc_server_selection_error (timeout_msg, &scanner_error, error); return 0; } 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); return 0; } loop_start = bson_get_monotonic_time (); if (loop_start > expire_at) { _mongoc_server_selection_error (timeout_msg, &scanner_error, error); return 0; } } else { server_id = selected_server->id; mongoc_mutex_unlock (&topology->mutex); return server_id; } } } /* *------------------------------------------------------------------------- * * 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_host_by_id -- * * Copy the mongoc_host_list_t 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 mongoc_host_list_t. * Callers must own and clean up this copy. * * NOTE: this method locks and unlocks @topology's mutex. * * Returns: * A mongoc_host_list_t, or NULL. * * Side effects: * Fills out optional @error if server not found. * *------------------------------------------------------------------------- */ mongoc_host_list_t * _mongoc_topology_host_by_id (mongoc_topology_t *topology, uint32_t id, bson_error_t *error) { mongoc_server_description_t *sd; mongoc_host_list_t *host = NULL; mongoc_mutex_lock (&topology->mutex); /* not a copy - direct pointer into topology description data */ sd = mongoc_topology_description_server_by_id ( &topology->description, id, error); if (sd) { host = bson_malloc0 (sizeof (mongoc_host_list_t)); memcpy (host, &sd->host, sizeof (mongoc_host_list_t)); } mongoc_mutex_unlock (&topology->mutex); return host; } /* *-------------------------------------------------------------------------- * * _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_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, const bson_error_t *error) { BSON_ASSERT (error); mongoc_mutex_lock (&topology->mutex); mongoc_topology_description_invalidate_server ( &topology->description, id, error); mongoc_mutex_unlock (&topology->mutex); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_update_from_handshake -- * * A client opens a new connection and calls ismaster on it when it * detects a closed connection in _mongoc_cluster_check_interval, or if * mongoc_client_pool_pop creates a new client. Update the topology * description from the ismaster response. * * NOTE: this method uses @topology's mutex. * * Returns: * false if the server was removed from the topology *-------------------------------------------------------------------------- */ bool _mongoc_topology_update_from_handshake (mongoc_topology_t *topology, const mongoc_server_description_t *sd) { bool has_server; BSON_ASSERT (topology); BSON_ASSERT (sd); mongoc_mutex_lock (&topology->mutex); mongoc_topology_description_handle_ismaster (&topology->description, sd->id, &sd->last_is_master, sd->round_trip_time_msec, NULL); /* return false if server was removed from topology */ has_server = mongoc_topology_description_server_by_id ( &topology->description, sd->id, NULL) != NULL; /* if pooled, wake threads waiting in mongoc_topology_server_by_id */ mongoc_cond_broadcast (&topology->cond_client); mongoc_mutex_unlock (&topology->mutex); return has_server; } /* *-------------------------------------------------------------------------- * * 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_get_type -- * * Return the topology's description's type. * * NOTE: this method uses @topology's mutex. * * Returns: * The topology description type. * *-------------------------------------------------------------------------- */ mongoc_topology_description_type_t _mongoc_topology_get_type (mongoc_topology_t *topology) { mongoc_topology_description_type_t td_type; mongoc_mutex_lock (&topology->mutex); td_type = topology->description.type; mongoc_mutex_unlock (&topology->mutex); return td_type; } /* *-------------------------------------------------------------------------- * * _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; int64_t heartbeat_msec; int r; BSON_ASSERT (data); last_scan = 0; topology = (mongoc_topology_t *) data; heartbeat_msec = topology->description.heartbeat_msec; /* 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 - (heartbeat_msec * 1000); } timeout = 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; /* scanning locks and unlocks the mutex itself until the scan is done */ mongoc_mutex_unlock (&topology->mutex); mongoc_topology_scanner_work (topology->scanner); mongoc_mutex_lock (&topology->mutex); _mongoc_topology_scanner_finish (topology->scanner); /* "retired" nodes can be checked again in the next scan */ mongoc_topology_scanner_reset (topology->scanner); topology->last_scan = bson_get_monotonic_time (); mongoc_mutex_unlock (&topology->mutex); last_scan = bson_get_monotonic_time (); } DONE: mongoc_mutex_unlock (&topology->mutex); return NULL; } /* *-------------------------------------------------------------------------- * * mongoc_topology_start_background_scanner * * 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. Returns whether or not the scanner is running on termination * of the function. * * NOTE: this method uses @topology's mutex. * *-------------------------------------------------------------------------- */ bool _mongoc_topology_start_background_scanner (mongoc_topology_t *topology) { int r; if (topology->single_threaded) { return false; } mongoc_mutex_lock (&topology->mutex); if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF) { topology->scanner_state = MONGOC_TOPOLOGY_SCANNER_BG_RUNNING; _mongoc_handshake_freeze (); _mongoc_topology_description_monitor_opening (&topology->description); r = mongoc_thread_create ( &topology->thread, _mongoc_topology_run_background, topology); if (r != 0) { MONGOC_ERROR ("could not start topology scanner thread: %s", strerror (r)); abort (); } } mongoc_mutex_unlock (&topology->mutex); return true; } /* *-------------------------------------------------------------------------- * * 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->scanner_state == MONGOC_TOPOLOGY_SCANNER_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->scanner_state = MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN; join_thread = true; } else if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_SHUTTING_DOWN) { /* if we're mid shutdown, wait until it shuts down */ while (topology->scanner_state != MONGOC_TOPOLOGY_SCANNER_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); } } bool _mongoc_topology_set_appname (mongoc_topology_t *topology, const char *appname) { bool ret = false; mongoc_mutex_lock (&topology->mutex); if (topology->scanner_state == MONGOC_TOPOLOGY_SCANNER_OFF) { ret = _mongoc_topology_scanner_set_appname (topology->scanner, appname); } else { MONGOC_ERROR ("Cannot set appname after handshake initiated"); } mongoc_mutex_unlock (&topology->mutex); return ret; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-trace-private.h0000664000175000017500000001033313210321137024005 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.3.4/src/libmongoc/src/mongoc/mongoc-uri-private.h0000664000175000017500000000207013210321137023505 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_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-uri.h" BSON_BEGIN_DECLS bool 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 downcase); int32_t mongoc_uri_get_local_threshold_option (const mongoc_uri_t *uri); BSON_END_DECLS #endif /* MONGOC_URI_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-uri.c0000664000175000017500000015400713210321137022040 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-config.h" #include "mongoc-host-list.h" #include "mongoc-host-list-private.h" #include "mongoc-log.h" #include "mongoc-handshake-private.h" #include "mongoc-socket.h" #include "mongoc-topology-private.h" #include "mongoc-uri-private.h" #include "mongoc-read-concern-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-compression-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; bson_t compressors; mongoc_read_prefs_t *read_prefs; mongoc_read_concern_t *read_concern; mongoc_write_concern_t *write_concern; }; #define MONGOC_URI_ERROR(error, format, ...) \ bson_set_error (error, \ MONGOC_ERROR_COMMAND, \ MONGOC_ERROR_COMMAND_INVALID_ARG, \ format, \ __VA_ARGS__); static const char *escape_instructions = "Percent-encode username and password" " according to RFC 3986."; bool _mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri, const char *option, int32_t value); static void mongoc_uri_do_unescape (char **str) { char *tmp; if ((tmp = *str)) { *str = mongoc_uri_unescape (tmp); bson_free (tmp); } } bool mongoc_uri_append_host (mongoc_uri_t *uri, const char *host, uint16_t port) { mongoc_host_list_t *iter; mongoc_host_list_t *link_; if (strlen (host) > BSON_HOST_NAME_MAX) { MONGOC_ERROR ("Hostname provided in URI is too long, max is %d chars", BSON_HOST_NAME_MAX); return false; } link_ = (mongoc_host_list_t *) bson_malloc0 (sizeof *link_); bson_strncpy (link_->host, 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 if (strstr (host, ".sock")) { bson_snprintf ( link_->host_and_port, sizeof link_->host_and_port, "%s", host); link_->family = AF_UNIX; } else { bson_snprintf (link_->host_and_port, sizeof link_->host_and_port, "%s:%hu", host, port); link_->family = 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_; } return true; } /* *-------------------------------------------------------------------------- * * 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; } /* *-------------------------------------------------------------------------- * * ends_with -- * * Return true if str ends with suffix. * *-------------------------------------------------------------------------- */ static bool ends_with (const char *str, const char *suffix) { size_t str_len = strlen (str); size_t suffix_len = strlen (suffix); const char *s1, *s2; if (str_len < suffix_len) { return false; } /* start at the ends of both strings */ s1 = str + str_len; s2 = suffix + suffix_len; /* until either pointer reaches start of its string, compare the pointers */ for (; s1 >= str && s2 >= suffix; s1--, s2--) { if (*s1 != *s2) { return false; } } return true; } 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_has_unescaped_chars (const char *str, const char *chars) { const char *c; const char *tmp; char *s; for (c = chars; *c; c++) { s = scan_to_unichar (str, (bson_unichar_t) *c, "", &tmp); if (s) { bson_free (s); return true; } } return false; } /* "str" is non-NULL, the part of URI between "mongodb://" and first "@" */ static bool mongoc_uri_parse_userpass (mongoc_uri_t *uri, const char *str, bson_error_t *error) { const char *prohibited = "@:/"; const char *end_user; BSON_ASSERT (str); if ((uri->username = scan_to_unichar (str, ':', "", &end_user))) { uri->password = bson_strdup (end_user + 1); } else { uri->username = bson_strdup (str); uri->password = NULL; } if (mongoc_uri_has_unescaped_chars (uri->username, prohibited)) { MONGOC_URI_ERROR (error, "Username \"%s\" must not have unescaped chars. %s", uri->username, escape_instructions); return false; } mongoc_uri_do_unescape (&uri->username); if (!uri->username) { MONGOC_URI_ERROR ( error, "Incorrect URI escapes in username. %s", escape_instructions); return false; } /* Providing password at all is optional */ if (uri->password) { if (mongoc_uri_has_unescaped_chars (uri->password, prohibited)) { MONGOC_URI_ERROR (error, "Password \"%s\" must not have unescaped chars. %s", uri->password, escape_instructions); return false; } mongoc_uri_do_unescape (&uri->password); if (!uri->password) { MONGOC_URI_ERROR (error, "%s", "Incorrect URI escapes in password."); return false; } } 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; bool r; if ((portstr = strrchr (str, ':')) && !strstr (portstr, "]")) { if (!mongoc_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_lowercase (hostname, hostname); r = mongoc_uri_append_host (uri, hostname, port); bson_free (hostname); return r; } bool mongoc_uri_parse_host (mongoc_uri_t *uri, const char *str, bool downcase) { uint16_t port; const char *end_host; char *hostname; bool r; if (*str == '\0') { MONGOC_WARNING ("Empty hostname in URI"); return false; } if (*str == '[' && strchr (str, ']')) { return mongoc_uri_parse_host6 (uri, str); } if ((hostname = scan_to_unichar (str, ':', "?/,", &end_host))) { end_host++; if (!mongoc_parse_port (&port, end_host)) { bson_free (hostname); return false; } } else { hostname = bson_strdup (str); port = MONGOC_DEFAULT_PORT; } if (mongoc_uri_has_unescaped_chars (hostname, "/")) { MONGOC_WARNING ("Unix Domain Sockets must be escaped (e.g. / = %%2F)"); bson_free (hostname); return false; } mongoc_uri_do_unescape (&hostname); if (!hostname) { /* invalid */ return false; } if (downcase) { mongoc_lowercase (hostname, hostname); } r = mongoc_uri_append_host (uri, hostname, port); bson_free (hostname); return r; } /* "hosts" is non-NULL, the part between "mongodb://" or "@" and last "/" */ static bool mongoc_uri_parse_hosts (mongoc_uri_t *uri, const char *hosts) { const char *next; const char *end_hostport; char *s; BSON_ASSERT (hosts); /* * 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 * ",". */ s = scan_to_unichar (hosts, '?', "", &end_hostport); if (s) { MONGOC_WARNING ( "%s", "A '/' is required between the host list and any options."); goto error; } next = hosts; do { /* makes a copy of the section of the string */ s = scan_to_unichar (next, ',', "", &end_hostport); if (s) { next = (char *) end_hostport + 1; } else { s = bson_strdup (next); next = NULL; } if (ends_with (s, ".sock")) { if (!mongoc_uri_parse_host (uri, s, false /* downcase */)) { goto error; } } else if (!mongoc_uri_parse_host (uri, s, true /* downcase */)) { goto error; } bson_free (s); } while (next); return true; error: bson_free (s); return false; } static bool mongoc_uri_parse_database (mongoc_uri_t *uri, const char *str, const char **end) { const char *end_database; const char *c; char *invalid_c; const char *tmp; 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; } /* invalid characters in database name */ for (c = "/\\. \"$"; *c; c++) { invalid_c = scan_to_unichar (uri->database, (bson_unichar_t) *c, "", &tmp); if (invalid_c) { bson_free (invalid_c); 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 */ mongoc_uri_set_mechanism_properties (uri, &properties); return true; } static bool 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_free (keyval); goto fail; } 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); } else if (strlen (str)) { /* we're not finished but we couldn't parse the string */ goto fail; } mongoc_read_prefs_add_tag (uri->read_prefs, &b); bson_destroy (&b); return true; fail: MONGOC_WARNING ("Unsupported value for \"" MONGOC_URI_READPREFERENCETAGS "\": \"%s\"", str); bson_destroy (&b); return false; } /* *-------------------------------------------------------------------------- * * 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, MONGOC_URI_CONNECTTIMEOUTMS) || !strcasecmp (key, MONGOC_URI_HEARTBEATFREQUENCYMS) || !strcasecmp (key, MONGOC_URI_SERVERSELECTIONTIMEOUTMS) || !strcasecmp (key, MONGOC_URI_SOCKETCHECKINTERVALMS) || !strcasecmp (key, MONGOC_URI_SOCKETTIMEOUTMS) || !strcasecmp (key, MONGOC_URI_LOCALTHRESHOLDMS) || !strcasecmp (key, MONGOC_URI_MAXPOOLSIZE) || !strcasecmp (key, MONGOC_URI_MAXSTALENESSSECONDS) || !strcasecmp (key, MONGOC_URI_MINPOOLSIZE) || !strcasecmp (key, MONGOC_URI_MAXIDLETIMEMS) || !strcasecmp (key, MONGOC_URI_WAITQUEUEMULTIPLE) || !strcasecmp (key, MONGOC_URI_WAITQUEUETIMEOUTMS) || !strcasecmp (key, MONGOC_URI_WTIMEOUTMS) || !strcasecmp (key, MONGOC_URI_ZLIBCOMPRESSIONLEVEL); } bool mongoc_uri_option_is_bool (const char *key) { return !strcasecmp (key, MONGOC_URI_CANONICALIZEHOSTNAME) || !strcasecmp (key, MONGOC_URI_JOURNAL) || !strcasecmp (key, MONGOC_URI_SAFE) || !strcasecmp (key, MONGOC_URI_SERVERSELECTIONTRYONCE) || !strcasecmp (key, MONGOC_URI_SLAVEOK) || !strcasecmp (key, MONGOC_URI_SSL) || !strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES) || !strcasecmp (key, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES); } bool mongoc_uri_option_is_utf8 (const char *key) { return !strcasecmp (key, MONGOC_URI_APPNAME) || !strcasecmp (key, MONGOC_URI_GSSAPISERVICENAME) || !strcasecmp (key, MONGOC_URI_REPLICASET) || !strcasecmp (key, MONGOC_URI_READPREFERENCE) || !strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE) || !strcasecmp (key, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD) || !strcasecmp (key, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE); } static bool mongoc_uri_parse_int32 (const char *key, const char *value, int32_t *result) { char *endptr; int64_t i; errno = 0; i = bson_ascii_strtoll (value, &endptr, 10); if (errno || endptr < value + strlen (value)) { MONGOC_WARNING ("Invalid %s: cannot parse integer\n", key); return false; } if (i > INT32_MAX || i < INT32_MIN) { MONGOC_WARNING ("Invalid %s: cannot fit in int32\n", key); return false; } *result = (int32_t) i; return true; } static bool mongoc_uri_parse_option (mongoc_uri_t *uri, const char *str) { int32_t v_int; const char *end_key; char *lkey = NULL; 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; } lkey = bson_strdup (key); mongoc_lowercase (key, lkey); if (bson_has_field (&uri->options, lkey)) { MONGOC_WARNING ("Overwriting previously provided value for '%s'", key); } if (mongoc_uri_option_is_int32 (lkey)) { if (!mongoc_uri_parse_int32 (lkey, value, &v_int)) { goto UNSUPPORTED_VALUE; } if (!mongoc_uri_set_option_as_int32 (uri, lkey, v_int)) { goto CLEANUP; } } else if (!strcmp (lkey, MONGOC_URI_W)) { if (*value == '-' || isdigit (*value)) { v_int = (int) strtol (value, NULL, 10); _mongoc_uri_set_option_as_int32 (uri, MONGOC_URI_W, v_int); } else if (0 == strcasecmp (value, "majority")) { mongoc_uri_bson_append_or_replace_key ( &uri->options, MONGOC_URI_W, "majority"); } else if (*value) { mongoc_uri_bson_append_or_replace_key ( &uri->options, MONGOC_URI_W, value); } } else if (mongoc_uri_option_is_bool (lkey)) { if (0 == strcasecmp (value, "true")) { mongoc_uri_set_option_as_bool (uri, lkey, true); } else if (0 == strcasecmp (value, "false")) { mongoc_uri_set_option_as_bool (uri, lkey, false); } else if ((0 == strcmp (value, "1")) || (0 == strcasecmp (value, "yes")) || (0 == strcasecmp (value, "y")) || (0 == strcasecmp (value, "t"))) { MONGOC_WARNING ("Deprecated boolean value for \"%1$s\": \"%2$s\", " "please update to \"%1$s=true\"", key, value); mongoc_uri_set_option_as_bool (uri, lkey, true); } else if ((0 == strcasecmp (value, "0")) || (0 == strcasecmp (value, "-1")) || (0 == strcmp (value, "no")) || (0 == strcmp (value, "n")) || (0 == strcmp (value, "f"))) { MONGOC_WARNING ("Deprecated boolean value for \"%1$s\": \"%2$s\", " "please update to \"%1$s=false\"", key, value); mongoc_uri_set_option_as_bool (uri, lkey, false); } else { goto UNSUPPORTED_VALUE; } } else if (!strcmp (lkey, MONGOC_URI_READPREFERENCETAGS)) { /* Allows providing this key multiple times */ if (!mongoc_uri_parse_tags (uri, value)) { goto UNSUPPORTED_VALUE; } } else if (!strcmp (lkey, MONGOC_URI_AUTHMECHANISM) || !strcmp (lkey, MONGOC_URI_AUTHSOURCE)) { if (bson_has_field (&uri->credentials, lkey)) { MONGOC_WARNING ("Overwriting previously provided value for '%s'", key); } mongoc_uri_bson_append_or_replace_key (&uri->credentials, lkey, value); } else if (!strcmp (lkey, MONGOC_URI_READCONCERNLEVEL)) { if (!mongoc_read_concern_is_default (uri->read_concern)) { MONGOC_WARNING ("Overwriting previously provided value for '%s'", key); } mongoc_read_concern_set_level (uri->read_concern, value); } else if (!strcmp (lkey, MONGOC_URI_AUTHMECHANISMPROPERTIES)) { if (bson_has_field (&uri->credentials, lkey)) { MONGOC_WARNING ("Overwriting previously provided value for '%s'", key); } if (!mongoc_uri_parse_auth_mechanism_properties (uri, value)) { goto UNSUPPORTED_VALUE; } } else if (!strcmp (lkey, MONGOC_URI_APPNAME)) { /* Part of uri->options */ if (!mongoc_uri_set_appname (uri, value)) { goto UNSUPPORTED_VALUE; } } else if (!strcmp (lkey, MONGOC_URI_COMPRESSORS)) { if (!mongoc_uri_set_compressors (uri, value)) { goto UNSUPPORTED_VALUE; } } else if (mongoc_uri_option_is_utf8 (lkey)) { mongoc_uri_bson_append_or_replace_key (&uri->options, lkey, value); } else { /* * Keys that aren't supported by a driver MUST be ignored. * * A WARN level logging message MUST be issued * https://github.com/mongodb/specifications/blob/master/source/connection-string/connection-string-spec.rst#keys */ MONGOC_WARNING ("Unsupported URI option \"%s\"", key); } ret = true; UNSUPPORTED_VALUE: if (!ret) { MONGOC_WARNING ("Unsupported value for \"%s\": \"%s\"", key, value); } CLEANUP: bson_free (key); bson_free (lkey); bson_free (value); return ret; } static bool mongoc_uri_parse_options (mongoc_uri_t *uri, const char *str, bson_error_t *error) { const char *end_option; char *option; again: if ((option = scan_to_unichar (str, '&', "", &end_option))) { if (!mongoc_uri_parse_option (uri, option)) { MONGOC_URI_ERROR (error, "Unknown option or value for '%s'", 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)) { MONGOC_URI_ERROR (error, "Unknown option or value for '%s'", str); return false; } } return true; } static bool mongoc_uri_finalize_auth (mongoc_uri_t *uri, bson_error_t *error) { 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, MONGOC_URI_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")) { MONGOC_URI_ERROR ( error, "%s", "GSSAPI and X509 require \"$external\" authSource"); return false; } } else { bson_append_utf8 ( &uri->credentials, MONGOC_URI_AUTHSOURCE, -1, "$external", -1); } } } return true; } static bool mongoc_uri_parse_before_slash (mongoc_uri_t *uri, const char *before_slash, bson_error_t *error) { char *userpass; const char *hosts; userpass = scan_to_unichar (before_slash, '@', "", &hosts); if (userpass) { if (!mongoc_uri_parse_userpass (uri, userpass, error)) { goto error; } hosts++; /* advance past "@" */ if (*hosts == '@') { /* special case: "mongodb://alice@@localhost" */ MONGOC_URI_ERROR ( error, "Invalid username or password. %s", escape_instructions); goto error; } } else { hosts = before_slash; } if (!mongoc_uri_parse_hosts (uri, hosts)) { MONGOC_URI_ERROR (error, "%s", "Invalid host string in URI"); goto error; } bson_free (userpass); return true; error: bson_free (userpass); return false; } static bool mongoc_uri_parse (mongoc_uri_t *uri, const char *str, bson_error_t *error) { char *before_slash = NULL; const char *tmp; if (!mongoc_uri_parse_scheme (str, &str)) { MONGOC_URI_ERROR ( error, "%s", "Invalid URI Schema, expecting 'mongodb://'"); goto error; } before_slash = scan_to_unichar (str, '/', "", &tmp); if (!before_slash) { before_slash = bson_strdup (str); str += strlen (before_slash); } else { str = tmp; } if (!mongoc_uri_parse_before_slash (uri, before_slash, error)) { goto error; } if (*str) { if (*str == '/') { str++; if (*str) { if (!mongoc_uri_parse_database (uri, str, &str)) { MONGOC_URI_ERROR (error, "%s", "Invalid database name in URI"); goto error; } } if (*str == '?') { str++; if (*str) { if (!mongoc_uri_parse_options (uri, str, error)) { goto error; } } } } else { MONGOC_URI_ERROR (error, "%s", "Expected end of hostname delimiter"); goto error; } } if (!mongoc_uri_finalize_auth (uri, error)) { goto error; } bson_free (before_slash); return true; error: bson_free (before_slash); return false; } 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, MONGOC_URI_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, MONGOC_URI_AUTHMECHANISM) && BSON_ITER_HOLDS_UTF8 (&iter)) { return bson_iter_utf8 (&iter, NULL); } return NULL; } bool mongoc_uri_set_auth_mechanism (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, MONGOC_URI_AUTHMECHANISM, value); return true; } bool mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri, bson_t *properties /* OUT */) { bson_iter_t iter; BSON_ASSERT (uri); BSON_ASSERT (properties); if (bson_iter_init_find_case ( &iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES) && 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; } bool mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri, const bson_t *properties) { bson_iter_t iter; bson_t tmp = BSON_INITIALIZER; bool r; BSON_ASSERT (uri); BSON_ASSERT (properties); if (bson_iter_init_find ( &iter, &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES)) { /* copy all elements to tmp besides authMechanismProperties */ bson_copy_to_excluding_noinit (&uri->credentials, &tmp, MONGOC_URI_AUTHMECHANISMPROPERTIES, (char *) NULL); r = BSON_APPEND_DOCUMENT ( &tmp, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties); if (!r) { bson_destroy (&tmp); return false; } bson_destroy (&uri->credentials); bson_copy_to (&tmp, &uri->credentials); bson_destroy (&tmp); return true; } else { return BSON_APPEND_DOCUMENT ( &uri->credentials, MONGOC_URI_AUTHMECHANISMPROPERTIES, properties); } } static bool _mongoc_uri_assign_read_prefs_mode (mongoc_uri_t *uri, bson_error_t *error) { const char *str; bson_iter_t iter; BSON_ASSERT (uri); if (mongoc_uri_get_option_as_bool (uri, MONGOC_URI_SLAVEOK, false)) { mongoc_read_prefs_set_mode (uri->read_prefs, MONGOC_READ_SECONDARY_PREFERRED); } if (bson_iter_init_find_case ( &iter, &uri->options, MONGOC_URI_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_URI_ERROR ( error, "Unsupported readPreference value [readPreference=%s].", str); return false; } } return true; } 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, MONGOC_URI_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, MONGOC_URI_WTIMEOUTMS, 0); if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_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, MONGOC_URI_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; } /* can't use mongoc_uri_get_option_as_int32, it treats 0 specially */ static int32_t _mongoc_uri_get_max_staleness_option (const mongoc_uri_t *uri) { const bson_t *options; bson_iter_t iter; int32_t retval = MONGOC_NO_MAX_STALENESS; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case ( &iter, options, MONGOC_URI_MAXSTALENESSSECONDS) && BSON_ITER_HOLDS_INT32 (&iter)) { retval = bson_iter_int32 (&iter); if (retval == 0) { MONGOC_WARNING ( "Unsupported value for \"" MONGOC_URI_MAXSTALENESSSECONDS "\": \"%d\"", retval); retval = -1; } else if (retval < 0 && retval != -1) { MONGOC_WARNING ( "Unsupported value for \"" MONGOC_URI_MAXSTALENESSSECONDS "\": \"%d\"", retval); retval = MONGOC_NO_MAX_STALENESS; } } return retval; } mongoc_uri_t * mongoc_uri_new_with_error (const char *uri_string, bson_error_t *error) { mongoc_uri_t *uri; int32_t max_staleness_seconds; uri = (mongoc_uri_t *) bson_malloc0 (sizeof *uri); bson_init (&uri->options); bson_init (&uri->credentials); bson_init (&uri->compressors); /* Initialize read_prefs, since 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, error)) { mongoc_uri_destroy (uri); return NULL; } uri->str = bson_strdup (uri_string); if (!_mongoc_uri_assign_read_prefs_mode (uri, error)) { mongoc_uri_destroy (uri); return NULL; } max_staleness_seconds = _mongoc_uri_get_max_staleness_option (uri); mongoc_read_prefs_set_max_staleness_seconds (uri->read_prefs, max_staleness_seconds); if (!mongoc_read_prefs_is_valid (uri->read_prefs)) { mongoc_uri_destroy (uri); MONGOC_URI_ERROR (error, "%s", "Invalid readPreferences"); return NULL; } _mongoc_uri_build_write_concern (uri); if (!mongoc_write_concern_is_valid (uri->write_concern)) { mongoc_uri_destroy (uri); MONGOC_URI_ERROR (error, "%s", "Invalid writeConcern"); return NULL; } return uri; } mongoc_uri_t * mongoc_uri_new (const char *uri_string) { bson_error_t error = {0}; mongoc_uri_t *uri; uri = mongoc_uri_new_with_error (uri_string, &error); if (error.domain) { MONGOC_WARNING ("Error parsing URI: '%s'", error.message); } 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, MONGOC_URI_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, MONGOC_URI_AUTHSOURCE, value); return true; } const char * mongoc_uri_get_appname (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return mongoc_uri_get_option_as_utf8 (uri, MONGOC_URI_APPNAME, NULL); } bool mongoc_uri_set_appname (mongoc_uri_t *uri, const char *value) { BSON_ASSERT (value); if (!bson_utf8_validate (value, strlen (value), false)) { return false; } if (!_mongoc_handshake_appname_is_valid (value)) { return false; } mongoc_uri_bson_append_or_replace_key ( &uri->options, MONGOC_URI_APPNAME, value); return true; } bool mongoc_uri_set_compressors (mongoc_uri_t *uri, const char *value) { const char *end_compressor; char *entry; bson_destroy (&uri->compressors); bson_init (&uri->compressors); if (value && !bson_utf8_validate (value, strlen (value), false)) { return false; } while ((entry = scan_to_unichar (value, ',', "", &end_compressor))) { if (mongoc_compressor_supported (entry)) { mongoc_uri_bson_append_or_replace_key ( &uri->compressors, entry, "yes"); } else { MONGOC_WARNING ("Unsupported compressor: '%s'", entry); } value = end_compressor + 1; bson_free (entry); } if (value) { if (mongoc_compressor_supported (value)) { mongoc_uri_bson_append_or_replace_key ( &uri->compressors, value, "yes"); } else { MONGOC_WARNING ("Unsupported compressor: '%s'", value); } } return true; } const bson_t * mongoc_uri_get_compressors (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return &uri->compressors; } /* can't use mongoc_uri_get_option_as_int32, it treats 0 specially */ int32_t mongoc_uri_get_local_threshold_option (const mongoc_uri_t *uri) { const bson_t *options; bson_iter_t iter; int32_t retval = MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, "localthresholdms") && BSON_ITER_HOLDS_INT32 (&iter)) { retval = bson_iter_int32 (&iter); if (retval < 0) { MONGOC_WARNING ("Invalid localThresholdMS: %d", retval); retval = MONGOC_TOPOLOGY_LOCAL_THRESHOLD_MS; } } return retval; } 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); bson_destroy (&uri->compressors); 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) { if (!mongoc_uri_append_host (copy, iter->host, iter->port)) { mongoc_uri_destroy (copy); return NULL; } } bson_copy_to (&uri->options, ©->options); bson_copy_to (&uri->credentials, ©->credentials); bson_copy_to (&uri->compressors, ©->compressors); 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() * or NULL on failure, such as invalid % encoding. * * 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); MONGOC_WARNING ("Invalid %% escape sequence"); 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; } void mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri, const mongoc_read_prefs_t *prefs) { BSON_ASSERT (uri); BSON_ASSERT (prefs); mongoc_read_prefs_destroy (uri->read_prefs); uri->read_prefs = mongoc_read_prefs_copy (prefs); } const mongoc_read_concern_t * mongoc_uri_get_read_concern (const mongoc_uri_t *uri) /* IN */ { BSON_ASSERT (uri); return uri->read_concern; } void mongoc_uri_set_read_concern (mongoc_uri_t *uri, const mongoc_read_concern_t *rc) { BSON_ASSERT (uri); BSON_ASSERT (rc); mongoc_read_concern_destroy (uri->read_concern); uri->read_concern = mongoc_read_concern_copy (rc); } const mongoc_write_concern_t * mongoc_uri_get_write_concern (const mongoc_uri_t *uri) /* IN */ { BSON_ASSERT (uri); return uri->write_concern; } void mongoc_uri_set_write_concern (mongoc_uri_t *uri, const mongoc_write_concern_t *wc) { BSON_ASSERT (uri); BSON_ASSERT (wc); mongoc_write_concern_destroy (uri->write_concern); uri->write_concern = mongoc_write_concern_copy (wc); } bool mongoc_uri_get_ssl (const mongoc_uri_t *uri) /* IN */ { bson_iter_t iter; BSON_ASSERT (uri); if (bson_iter_init_find_case (&iter, &uri->options, MONGOC_URI_SSL) && BSON_ITER_HOLDS_BOOL (&iter)) { return bson_iter_bool (&iter); } if (bson_has_field (&uri->options, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE) || bson_has_field (&uri->options, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE) || bson_has_field (&uri->options, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES) || bson_has_field (&uri->options, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES)) { return true; } return false; } /* *-------------------------------------------------------------------------- * * 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) { BSON_ASSERT (option); if (!mongoc_uri_option_is_int32 (option)) { return false; } /* Server Discovery and Monitoring Spec: "the driver MUST NOT permit users to * configure it less than minHeartbeatFrequencyMS (500ms)." */ if (!bson_strcasecmp (option, MONGOC_URI_HEARTBEATFREQUENCYMS) && value < MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS) { MONGOC_WARNING ("Invalid \"%s\" of %d: must be at least %d", option, value, MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS); return false; } /* zlib levels are from -1 (default) through 9 (best compression) */ if (!bson_strcasecmp (option, MONGOC_URI_ZLIBCOMPRESSIONLEVEL) && (value < -1 || value > 9)) { MONGOC_WARNING ( "Invalid \"%s\" of %d: must be between -1 and 9", option, value); return false; } return _mongoc_uri_set_option_as_int32 (uri, option, value); } /* *-------------------------------------------------------------------------- * * _mongoc_uri_set_option_as_int32 -- * * Same as mongoc_uri_set_option_as_int32, except the option is not * validated against valid int32 options * * 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; 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; } if (!bson_strcasecmp (option, MONGOC_URI_APPNAME)) { return mongoc_uri_set_appname (uri, value); } else { mongoc_uri_bson_append_or_replace_key (&uri->options, option, value); } return true; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-uri.h0000664000175000017500000001716713210321137022052 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-macros.h" #include "mongoc-host-list.h" #include "mongoc-read-prefs.h" #include "mongoc-read-concern.h" #include "mongoc-write-concern.h" #include "mongoc-config.h" #ifndef MONGOC_DEFAULT_PORT #define MONGOC_DEFAULT_PORT 27017 #endif #define MONGOC_URI_APPNAME "appname" #define MONGOC_URI_AUTHMECHANISM "authmechanism" #define MONGOC_URI_AUTHMECHANISMPROPERTIES "authmechanismproperties" #define MONGOC_URI_AUTHSOURCE "authsource" #define MONGOC_URI_CANONICALIZEHOSTNAME "canonicalizehostname" #define MONGOC_URI_CONNECTTIMEOUTMS "connecttimeoutms" #define MONGOC_URI_COMPRESSORS "compressors" #define MONGOC_URI_GSSAPISERVICENAME "gssapiservicename" #define MONGOC_URI_HEARTBEATFREQUENCYMS "heartbeatfrequencyms" #define MONGOC_URI_JOURNAL "journal" #define MONGOC_URI_LOCALTHRESHOLDMS "localthresholdms" #define MONGOC_URI_MAXIDLETIMEMS "maxidletimems" #define MONGOC_URI_MAXPOOLSIZE "maxpoolsize" #define MONGOC_URI_MAXSTALENESSSECONDS "maxstalenessseconds" #define MONGOC_URI_MINPOOLSIZE "minpoolsize" #define MONGOC_URI_READCONCERNLEVEL "readconcernlevel" #define MONGOC_URI_READPREFERENCE "readpreference" #define MONGOC_URI_READPREFERENCETAGS "readpreferencetags" #define MONGOC_URI_REPLICASET "replicaset" #define MONGOC_URI_SAFE "safe" #define MONGOC_URI_SERVERSELECTIONTIMEOUTMS "serverselectiontimeoutms" #define MONGOC_URI_SERVERSELECTIONTRYONCE "serverselectiontryonce" #define MONGOC_URI_SLAVEOK "slaveok" #define MONGOC_URI_SOCKETCHECKINTERVALMS "socketcheckintervalms" #define MONGOC_URI_SOCKETTIMEOUTMS "sockettimeoutms" #define MONGOC_URI_SSL "ssl" #define MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE "sslclientcertificatekeyfile" #define MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD \ "sslclientcertificatekeypassword" #define MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE "sslcertificateauthorityfile" #define MONGOC_URI_SSLALLOWINVALIDCERTIFICATES "sslallowinvalidcertificates" #define MONGOC_URI_SSLALLOWINVALIDHOSTNAMES "sslallowinvalidhostnames" #define MONGOC_URI_W "w" #define MONGOC_URI_WAITQUEUEMULTIPLE "waitqueuemultiple" #define MONGOC_URI_WAITQUEUETIMEOUTMS "waitqueuetimeoutms" #define MONGOC_URI_WTIMEOUTMS "wtimeoutms" #define MONGOC_URI_ZLIBCOMPRESSIONLEVEL "zlibcompressionlevel" BSON_BEGIN_DECLS typedef struct _mongoc_uri_t mongoc_uri_t; MONGOC_EXPORT (mongoc_uri_t *) mongoc_uri_copy (const mongoc_uri_t *uri); MONGOC_EXPORT (void) mongoc_uri_destroy (mongoc_uri_t *uri); MONGOC_EXPORT (mongoc_uri_t *) mongoc_uri_new (const char *uri_string) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (mongoc_uri_t *) mongoc_uri_new_with_error (const char *uri_string, bson_error_t *error) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (mongoc_uri_t *) mongoc_uri_new_for_host_port (const char *hostname, uint16_t port) BSON_GNUC_WARN_UNUSED_RESULT; MONGOC_EXPORT (const mongoc_host_list_t *) mongoc_uri_get_hosts (const mongoc_uri_t *uri); MONGOC_EXPORT (const char *) mongoc_uri_get_database (const mongoc_uri_t *uri); MONGOC_EXPORT (bool) mongoc_uri_set_database (mongoc_uri_t *uri, const char *database); MONGOC_EXPORT (const bson_t *) mongoc_uri_get_compressors (const mongoc_uri_t *uri); MONGOC_EXPORT (const bson_t *) mongoc_uri_get_options (const mongoc_uri_t *uri); MONGOC_EXPORT (const char *) mongoc_uri_get_password (const mongoc_uri_t *uri); MONGOC_EXPORT (bool) mongoc_uri_set_password (mongoc_uri_t *uri, const char *password); MONGOC_EXPORT (bool) mongoc_uri_option_is_int32 (const char *key); MONGOC_EXPORT (bool) mongoc_uri_option_is_bool (const char *key); MONGOC_EXPORT (bool) mongoc_uri_option_is_utf8 (const char *key); MONGOC_EXPORT (int32_t) mongoc_uri_get_option_as_int32 (const mongoc_uri_t *uri, const char *option, int32_t fallback); MONGOC_EXPORT (bool) mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri, const char *option, bool fallback); MONGOC_EXPORT (const char *) mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri, const char *option, const char *fallback); MONGOC_EXPORT (bool) mongoc_uri_set_option_as_int32 (mongoc_uri_t *uri, const char *option, int32_t value); MONGOC_EXPORT (bool) mongoc_uri_set_option_as_bool (mongoc_uri_t *uri, const char *option, bool value); MONGOC_EXPORT (bool) mongoc_uri_set_option_as_utf8 (mongoc_uri_t *uri, const char *option, const char *value); MONGOC_EXPORT (const bson_t *) mongoc_uri_get_read_prefs (const mongoc_uri_t *uri) BSON_GNUC_DEPRECATED_FOR (mongoc_uri_get_read_prefs_t); MONGOC_EXPORT (const char *) mongoc_uri_get_replica_set (const mongoc_uri_t *uri); MONGOC_EXPORT (const char *) mongoc_uri_get_string (const mongoc_uri_t *uri); MONGOC_EXPORT (const char *) mongoc_uri_get_username (const mongoc_uri_t *uri); MONGOC_EXPORT (bool) mongoc_uri_set_username (mongoc_uri_t *uri, const char *username); MONGOC_EXPORT (const bson_t *) mongoc_uri_get_credentials (const mongoc_uri_t *uri); MONGOC_EXPORT (const char *) mongoc_uri_get_auth_source (const mongoc_uri_t *uri); MONGOC_EXPORT (bool) mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value); MONGOC_EXPORT (const char *) mongoc_uri_get_appname (const mongoc_uri_t *uri); MONGOC_EXPORT (bool) mongoc_uri_set_appname (mongoc_uri_t *uri, const char *value); MONGOC_EXPORT (bool) mongoc_uri_set_compressors (mongoc_uri_t *uri, const char *value); MONGOC_EXPORT (const char *) mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri); MONGOC_EXPORT (bool) mongoc_uri_set_auth_mechanism (mongoc_uri_t *uri, const char *value); MONGOC_EXPORT (bool) mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri, bson_t *properties); MONGOC_EXPORT (bool) mongoc_uri_set_mechanism_properties (mongoc_uri_t *uri, const bson_t *properties); MONGOC_EXPORT (bool) mongoc_uri_get_ssl (const mongoc_uri_t *uri); MONGOC_EXPORT (char *) mongoc_uri_unescape (const char *escaped_string); MONGOC_EXPORT (const mongoc_read_prefs_t *) mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri); MONGOC_EXPORT (void) mongoc_uri_set_read_prefs_t (mongoc_uri_t *uri, const mongoc_read_prefs_t *prefs); MONGOC_EXPORT (const mongoc_write_concern_t *) mongoc_uri_get_write_concern (const mongoc_uri_t *uri); MONGOC_EXPORT (void) mongoc_uri_set_write_concern (mongoc_uri_t *uri, const mongoc_write_concern_t *wc); MONGOC_EXPORT (const mongoc_read_concern_t *) mongoc_uri_get_read_concern (const mongoc_uri_t *uri); MONGOC_EXPORT (void) mongoc_uri_set_read_concern (mongoc_uri_t *uri, const mongoc_read_concern_t *rc); BSON_END_DECLS #endif /* MONGOC_URI_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-util-private.h0000664000175000017500000000613313210321137023667 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_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc.h" #ifdef HAVE_STRINGS_H #include #endif /* 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 #if BSON_GNUC_CHECK_VERSION (4, 6) #define BEGIN_IGNORE_DEPRECATIONS \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #define END_IGNORE_DEPRECATIONS _Pragma ("GCC diagnostic pop") #elif defined(__clang__) #define BEGIN_IGNORE_DEPRECATIONS \ _Pragma ("clang diagnostic push") \ _Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"") #define END_IGNORE_DEPRECATIONS _Pragma ("clang diagnostic pop") #else #define BEGIN_IGNORE_DEPRECATIONS #define END_IGNORE_DEPRECATIONS #endif #define COALESCE(x, y) ((x == 0) ? (y) : (x)) /* Helper macros for stringifying things */ #define MONGOC_STR(s) #s #define MONGOC_EVALUATE_STR(s) MONGOC_STR (s) BSON_BEGIN_DECLS int _mongoc_rand_simple (unsigned int *seed); 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); size_t _mongoc_strlen_or_zero (const char *s); bool _mongoc_get_server_id_from_opts (const bson_t *opts, mongoc_error_domain_t domain, mongoc_error_code_t code, uint32_t *server_id, bson_error_t *error); bool _mongoc_validate_legacy_index (const bson_t *doc, bson_error_t *error); bool _mongoc_validate_new_document (const bson_t *insert, bson_error_t *error); bool _mongoc_validate_replace (const bson_t *insert, bson_error_t *error); bool _mongoc_validate_update (const bson_t *update, bson_error_t *error); void mongoc_lowercase (const char *src, char *buf /* OUT */); bool mongoc_parse_port (uint16_t *port, const char *str); BSON_END_DECLS #endif /* MONGOC_UTIL_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-util.c0000664000175000017500000001722613210321137022217 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" #include "mongoc-trace-private.h" int _mongoc_rand_simple (unsigned int *seed) { #ifdef _WIN32 /* ignore the seed */ unsigned int ret = 0; errno_t err; err = rand_s (&ret); if (0 != err) { MONGOC_ERROR ("rand_s failed: %"); } return (int) ret; #else return rand_r (seed); #endif } 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; const char *name; bson_iter_t child; const char *wrapper_name = NULL; BSON_ASSERT (command); if (!bson_iter_init (&iter, command) || !bson_iter_next (&iter)) { return NULL; } name = bson_iter_key (&iter); /* wrapped in "$query" or "query"? * * {$query: {count: "collection"}, $readPreference: {...}} */ if (name[0] == '$') { wrapper_name = "$query"; } else if (!strcmp (name, "query")) { wrapper_name = "query"; } if (wrapper_name && bson_iter_init_find (&iter, command, wrapper_name) && BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child) && bson_iter_next (&child)) { name = bson_iter_key (&child); } return name; } 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); } } size_t _mongoc_strlen_or_zero (const char *s) { return s ? strlen (s) : 0; } /* Get "serverId" from opts. Sets *server_id to the serverId from "opts" or 0 * if absent. On error, fills out *error with domain and code and return false. */ bool _mongoc_get_server_id_from_opts (const bson_t *opts, mongoc_error_domain_t domain, mongoc_error_code_t code, uint32_t *server_id, bson_error_t *error) { bson_iter_t iter; ENTRY; BSON_ASSERT (server_id); *server_id = 0; if (!opts || !bson_iter_init_find (&iter, opts, "serverId")) { RETURN (true); } if (!BSON_ITER_HOLDS_INT (&iter)) { bson_set_error ( error, domain, code, "The serverId option must be an integer"); RETURN (false); } if (bson_iter_as_int64 (&iter) <= 0) { bson_set_error (error, domain, code, "The serverId option must be >= 1"); RETURN (false); } *server_id = (uint32_t) bson_iter_as_int64 (&iter); RETURN (true); } bool _mongoc_validate_legacy_index (const bson_t *doc, bson_error_t *error) { bson_error_t validate_err; /* insert into system.indexes on pre-2.6 MongoDB, allow "." in keys */ if (!bson_validate_with_error (doc, BSON_VALIDATE_UTF8 | BSON_VALIDATE_EMPTY_KEYS | BSON_VALIDATE_DOLLAR_KEYS, &validate_err)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "legacy index document contains invalid key: %s", validate_err.message); return false; } return true; } const bson_validate_flags_t insert_vflags = (bson_validate_flags_t) BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_EMPTY_KEYS | BSON_VALIDATE_DOT_KEYS | BSON_VALIDATE_DOLLAR_KEYS; bool _mongoc_validate_new_document (const bson_t *doc, bson_error_t *error) { bson_error_t validate_err; if (!bson_validate_with_error (doc, insert_vflags, &validate_err)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "document to insert contains invalid key: %s", validate_err.message); return false; } return true; } bool _mongoc_validate_replace (const bson_t *doc, bson_error_t *error) { bson_error_t validate_err; if (!bson_validate_with_error (doc, insert_vflags, &validate_err)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "replacement document contains invalid key: %s", validate_err.message); return false; } return true; } bool _mongoc_validate_update (const bson_t *update, bson_error_t *error) { bson_error_t validate_err; bson_iter_t iter; const char *key; int vflags = BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_EMPTY_KEYS; if (!bson_validate_with_error ( update, (bson_validate_flags_t) vflags, &validate_err)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "update document contains invalid key: %s", validate_err.message); return false; } if (!bson_iter_init (&iter, update)) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "update document is corrupt"); return false; } while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (key[0] != '$') { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Invalid key '%s': update only works with $ operators", key); return false; } } return true; } void mongoc_lowercase (const char *src, char *buf /* OUT */) { for (; *src; ++src, ++buf) { *buf = tolower (*src); } } bool mongoc_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; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-version-functions.c0000664000175000017500000000330313210321137024724 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.3.4/src/libmongoc/src/mongoc/mongoc-version-functions.h0000664000175000017500000000241213210321137024731 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 /* for "bool" */ #include "mongoc-macros.h" BSON_BEGIN_DECLS MONGOC_EXPORT (int) mongoc_get_major_version (void); MONGOC_EXPORT (int) mongoc_get_minor_version (void); MONGOC_EXPORT (int) mongoc_get_micro_version (void); MONGOC_EXPORT (const char *) mongoc_get_version (void); MONGOC_EXPORT (bool) mongoc_check_version (int required_major, int required_minor, int required_micro); BSON_END_DECLS #endif /* MONGOC_VERSION_FUNCTIONS_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-version.h0000664000175000017500000000465013210321137022731 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 (8) /** * MONGOC_MICRO_VERSION: * * MONGOC micro version component (e.g. 3 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MICRO_VERSION (2) /** * 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.8.2) /** * MONGOC_VERSION_S: * * MONGOC version, encoded as a string, useful for printing and * concatenation. */ #define MONGOC_VERSION_S "1.8.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.3.4/src/libmongoc/src/mongoc/mongoc-version.h.in0000664000175000017500000000503013210321137023327 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.3.4/src/libmongoc/src/mongoc/mongoc-write-command-private.h0000664000175000017500000001305413210321137025460 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_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; bool has_collation; }; typedef struct { int type; bson_t *documents; uint32_t n_documents; mongoc_bulk_write_flags_t flags; int64_t operation_id; union { 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; /* The command failed */ bool must_stop; /* The stream may have been disonnected */ 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, int64_t operation_id, bool allow_bulk_op_insert); void _mongoc_write_command_init_delete (mongoc_write_command_t *command, const bson_t *selectors, const bson_t *opts, mongoc_bulk_write_flags_t flags, int64_t operation_id); void _mongoc_write_command_init_update (mongoc_write_command_t *command, const bson_t *selector, const bson_t *update, const bson_t *opts, mongoc_bulk_write_flags_t flags, int64_t operation_id); 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, const bson_t *opts); void _mongoc_write_command_delete_append (mongoc_write_command_t *command, const bson_t *selector, const bson_t *opts); 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, int32_t error_api_version, mongoc_error_code_t default_code, uint32_t offset); bool _mongoc_write_result_complete (mongoc_write_result_t *result, int32_t error_api_version, const mongoc_write_concern_t *wc, mongoc_error_domain_t err_domain_override, 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.3.4/src/libmongoc/src/mongoc/mongoc-write-command.c0000664000175000017500000017401613210321137024011 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-private.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_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); static bool _is_duplicate_key_error (int32_t code) { return code == 11000 || code == 16460 || /* see SERVER-11493 */ code == 11001 || /* duplicate key for updates before 2.6 */ code == 12582; /* mongos before 2.6 */ } 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, const bson_t *opts) { 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); if (opts) { bson_concat (&doc, opts); command->flags.has_collation |= bson_has_field (opts, "collation"); } 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 bson_t *opts) { 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); if (opts) { bson_concat (&doc, opts); command->flags.has_collation |= bson_has_field (opts, "collation"); } 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 */ int64_t operation_id, /* 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->operation_id = operation_id; /* 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 */ const bson_t *opts, /* IN */ mongoc_bulk_write_flags_t flags, /* IN */ int64_t operation_id) /* IN */ { ENTRY; BSON_ASSERT (command); BSON_ASSERT (selector); command->type = MONGOC_WRITE_COMMAND_DELETE; command->documents = bson_new (); command->n_documents = 0; command->flags = flags; command->operation_id = operation_id; _mongoc_write_command_delete_append (command, selector, opts); EXIT; } void _mongoc_write_command_init_update (mongoc_write_command_t *command, /* IN */ const bson_t *selector, /* IN */ const bson_t *update, /* IN */ const bson_t *opts, /* IN */ mongoc_bulk_write_flags_t flags, /* IN */ int64_t operation_id) /* 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->operation_id = operation_id; _mongoc_write_command_update_append (command, selector, update, opts); EXIT; } /* takes initialized bson_t *doc and begins formatting a write command */ static void _mongoc_write_command_init (bson_t *doc, mongoc_write_command_t *command, const char *collection, const mongoc_write_concern_t *write_concern) { bson_iter_t iter; ENTRY; if (!command->n_documents || !bson_iter_init (&iter, command->documents) || !bson_iter_next (&iter)) { EXIT; } BSON_APPEND_UTF8 (doc, gCommandNames[command->type], collection); BSON_APPEND_DOCUMENT ( doc, "writeConcern", WRITE_CONCERN_DOC (write_concern)); BSON_APPEND_BOOL (doc, "ordered", command->flags.ordered); if (command->flags.bypass_document_validation != MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT) { BSON_APPEND_BOOL (doc, "bypassDocumentValidation", !!command->flags.bypass_document_validation); } EXIT; } static void _mongoc_monitor_legacy_write (mongoc_client_t *client, mongoc_write_command_t *command, const char *db, const char *collection, const mongoc_write_concern_t *write_concern, mongoc_server_stream_t *stream, int64_t request_id) { bson_t doc; mongoc_apm_command_started_t event; ENTRY; if (!client->apm_callbacks.started) { EXIT; } bson_init (&doc); _mongoc_write_command_init (&doc, command, collection, write_concern); /* copy the whole documents buffer as e.g. "updates": [...] */ BSON_APPEND_ARRAY (&doc, gCommandFields[command->type], command->documents); mongoc_apm_command_started_init (&event, &doc, db, gCommandNames[command->type], request_id, command->operation_id, &stream->sd->host, stream->sd->id, client->apm_context); client->apm_callbacks.started (&event); mongoc_apm_command_started_cleanup (&event); bson_destroy (&doc); } static void append_write_err (bson_t *doc, uint32_t code, const char *errmsg, size_t errmsg_len, const bson_t *errinfo) { bson_t array = BSON_INITIALIZER; bson_t child; BSON_ASSERT (errmsg); /* writeErrors: [{index: 0, code: code, errmsg: errmsg, errInfo: {...}}] */ bson_append_document_begin (&array, "0", 1, &child); bson_append_int32 (&child, "index", 5, 0); bson_append_int32 (&child, "code", 4, (int32_t) code); bson_append_utf8 (&child, "errmsg", 6, errmsg, (int) errmsg_len); if (errinfo) { bson_append_document (&child, "errInfo", 7, errinfo); } bson_append_document_end (&array, &child); bson_append_array (doc, "writeErrors", 11, &array); bson_destroy (&array); } static void append_write_concern_err (bson_t *doc, const char *errmsg, size_t errmsg_len) { bson_t array = BSON_INITIALIZER; bson_t child; bson_t errinfo; BSON_ASSERT (errmsg); /* writeConcernErrors: [{code: 64, * errmsg: errmsg, * errInfo: {wtimeout: true}}] */ bson_append_document_begin (&array, "0", 1, &child); bson_append_int32 (&child, "code", 4, 64); bson_append_utf8 (&child, "errmsg", 6, errmsg, (int) errmsg_len); bson_append_document_begin (&child, "errInfo", 7, &errinfo); bson_append_bool (&errinfo, "wtimeout", 8, true); bson_append_document_end (&child, &errinfo); bson_append_document_end (&array, &child); bson_append_array (doc, "writeConcernErrors", 18, &array); bson_destroy (&array); } static bool get_upserted_id (const bson_t *update, bson_value_t *upserted_id) { bson_iter_t iter; bson_iter_t id_iter; /* Versions of MongoDB before 2.6 don't return the _id for an upsert if _id * is not an ObjectId, so find it in the update document's query "q" or * update "u". It must be in one or both: if it were in neither the _id * would be server-generated, therefore an ObjectId, therefore returned and * we wouldn't call this function. If _id is in both the update document * *and* the query spec the update document _id takes precedence. */ bson_iter_init (&iter, update); if (bson_iter_find_descendant (&iter, "u._id", &id_iter)) { bson_value_copy (bson_iter_value (&id_iter), upserted_id); return true; } else { bson_iter_init (&iter, update); if (bson_iter_find_descendant (&iter, "q._id", &id_iter)) { bson_value_copy (bson_iter_value (&id_iter), upserted_id); return true; } } /* server bug? */ return false; } static void append_upserted (bson_t *doc, const bson_value_t *upserted_id) { bson_t array = BSON_INITIALIZER; bson_t child; /* append upserted: [{index: 0, _id: upserted_id}]*/ bson_append_document_begin (&array, "0", 1, &child); bson_append_int32 (&child, "index", 5, 0); bson_append_value (&child, "_id", 3, upserted_id); bson_append_document_end (&array, &child); bson_append_array (doc, "upserted", 8, &array); bson_destroy (&array); } /* fire command-succeeded event as if we'd used a modern write command. * note, cluster.request_id was incremented once for the write, again * for the getLastError, so cluster.request_id is no longer valid; used the * passed-in request_id instead. */ static void _mongoc_monitor_legacy_write_succeeded (mongoc_client_t *client, int64_t duration, mongoc_write_command_t *command, const bson_t *gle, mongoc_server_stream_t *stream, int64_t request_id) { bson_iter_t iter; bson_t doc; int64_t ok = 1; int64_t n = 0; uint32_t code = 8; bool wtimeout = false; /* server error message */ const char *errmsg = NULL; size_t errmsg_len = 0; /* server errInfo subdocument */ bool has_errinfo = false; uint32_t len; const uint8_t *data; bson_t errinfo; /* server upsertedId value */ bool has_upserted_id = false; bson_value_t upserted_id; /* server updatedExisting value */ bool has_updated_existing = false; bool updated_existing = false; mongoc_apm_command_succeeded_t event; ENTRY; if (!client->apm_callbacks.succeeded) { EXIT; } /* first extract interesting fields from getlasterror response */ if (gle) { bson_iter_init (&iter, gle); while (bson_iter_next (&iter)) { if (!strcmp (bson_iter_key (&iter), "ok")) { ok = bson_iter_as_int64 (&iter); } else if (!strcmp (bson_iter_key (&iter), "n")) { n = bson_iter_as_int64 (&iter); } else if (!strcmp (bson_iter_key (&iter), "code")) { code = (uint32_t) bson_iter_as_int64 (&iter); if (code == 0) { /* server sent non-numeric error code? */ code = 8; } } else if (!strcmp (bson_iter_key (&iter), "upserted")) { has_upserted_id = true; bson_value_copy (bson_iter_value (&iter), &upserted_id); } else if (!strcmp (bson_iter_key (&iter), "updatedExisting")) { has_updated_existing = true; updated_existing = bson_iter_as_bool (&iter); } else if ((!strcmp (bson_iter_key (&iter), "err") || !strcmp (bson_iter_key (&iter), "errmsg")) && BSON_ITER_HOLDS_UTF8 (&iter)) { errmsg = bson_iter_utf8_unsafe (&iter, &errmsg_len); } else if (!strcmp (bson_iter_key (&iter), "errInfo") && BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_iter_document (&iter, &len, &data); bson_init_static (&errinfo, data, len); has_errinfo = true; } else if (!strcmp (bson_iter_key (&iter), "wtimeout")) { wtimeout = true; } } } /* based on PyMongo's _convert_write_result() */ bson_init (&doc); bson_append_int32 (&doc, "ok", 2, (int32_t) ok); if (errmsg && !wtimeout) { /* Failure, but pass to the success callback. Command Monitoring Spec: * "Commands that executed on the server and return a status of {ok: 1} * are considered successful commands and fire CommandSucceededEvent. * Commands that have write errors are included since the actual command * did succeed, only writes failed." */ append_write_err ( &doc, code, errmsg, errmsg_len, has_errinfo ? &errinfo : NULL); } else { /* Success, perhaps with a writeConcernError. */ if (errmsg) { append_write_concern_err (&doc, errmsg, errmsg_len); } if (command->type == MONGOC_WRITE_COMMAND_INSERT) { /* GLE result for insert is always 0 in most MongoDB versions. */ n = command->n_documents; } else if (command->type == MONGOC_WRITE_COMMAND_UPDATE) { if (has_upserted_id) { append_upserted (&doc, &upserted_id); } else if (has_updated_existing && !updated_existing && n == 1) { has_upserted_id = get_upserted_id (&command->documents[0], &upserted_id); if (has_upserted_id) { append_upserted (&doc, &upserted_id); } } } } bson_append_int32 (&doc, "n", 1, (int32_t) n); mongoc_apm_command_succeeded_init (&event, duration, &doc, gCommandNames[command->type], request_id, command->operation_id, &stream->sd->host, stream->sd->id, client->apm_context); client->apm_callbacks.succeeded (&event); mongoc_apm_command_succeeded_cleanup (&event); bson_destroy (&doc); if (has_upserted_id) { bson_value_destroy (&upserted_id); } 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) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "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", MONGOC_ERROR_BSON_INVALID); } } 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) { int64_t started; int32_t max_bson_obj_size; const uint8_t *data; mongoc_rpc_t rpc; uint32_t request_id; bson_iter_t iter; bson_iter_t q_iter; uint32_t len; int64_t limit = 0; 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); started = bson_get_monotonic_time (); max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); r = bson_iter_init (&iter, command->documents); BSON_ASSERT (r); 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)); BSON_ASSERT (r); bson_iter_document (&q_iter, &len, &data); BSON_ASSERT (data); BSON_ASSERT (len >= 5); if (len > max_bson_obj_size) { too_large_error (error, 0, len, max_bson_obj_size, NULL); result->failed = true; EXIT; } request_id = ++client->cluster.request_id; rpc.header.msg_len = 0; rpc.header.request_id = request_id; rpc.header.response_to = 0; rpc.header.opcode = MONGOC_OPCODE_DELETE; rpc.delete_.zero = 0; rpc.delete_.collection = ns; if (bson_iter_find (&q_iter, "limit") && (BSON_ITER_HOLDS_INT (&q_iter))) { limit = bson_iter_as_int64 (&q_iter); } rpc.delete_.flags = limit ? MONGOC_DELETE_SINGLE_REMOVE : MONGOC_DELETE_NONE; rpc.delete_.selector = data; _mongoc_monitor_legacy_write (client, command, database, collection, write_concern, server_stream, request_id); if (!mongoc_cluster_sendv_to_server ( &client->cluster, &rpc, server_stream, write_concern, error)) { result->failed = true; EXIT; } if (mongoc_write_concern_is_acknowledged (write_concern)) { if (!_mongoc_client_recv_gle (client, server_stream, &gle, error)) { result->failed = true; EXIT; } _mongoc_write_result_merge_legacy ( result, command, gle, client->error_api_version, MONGOC_ERROR_COLLECTION_DELETE_FAILED, offset); offset++; } _mongoc_monitor_legacy_write_succeeded (client, bson_get_monotonic_time () - started, command, gle, server_stream, request_id); if (gle) { bson_destroy (gle); gle = NULL; } started = bson_get_monotonic_time (); } while (bson_iter_next (&iter)); EXIT; } 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) { int64_t started; 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 request_id = 0; 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); started = bson_get_monotonic_time (); 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); BSON_ASSERT (r); 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, client->error_api_version, 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) { request_id = ++client->cluster.request_id; rpc.header.msg_len = 0; rpc.header.request_id = request_id; rpc.header.response_to = 0; rpc.header.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; _mongoc_monitor_legacy_write (client, command, database, collection, write_concern, server_stream, request_id); if (!mongoc_cluster_sendv_to_server ( &client->cluster, &rpc, server_stream, write_concern, error)) { result->failed = true; GOTO (cleanup); } if (mongoc_write_concern_is_acknowledged (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); } } _mongoc_monitor_legacy_write_succeeded (client, bson_get_monotonic_time () - started, command, gle, server_stream, request_id); started = bson_get_monotonic_time (); } cleanup: if (gle) { _mongoc_write_result_merge_legacy (result, command, gle, client->error_api_version, 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) { int64_t started; int32_t max_bson_obj_size; mongoc_rpc_t rpc; uint32_t request_id = 0; 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); started = bson_get_monotonic_time (); max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); 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)) { request_id = ++client->cluster.request_id; rpc.header.msg_len = 0; rpc.header.request_id = request_id; rpc.header.response_to = 0; rpc.header.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); if (len > max_bson_obj_size) { too_large_error (error, 0, len, max_bson_obj_size, NULL); result->failed = true; EXIT; } 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); if (len > max_bson_obj_size) { too_large_error (error, 0, len, max_bson_obj_size, NULL); result->failed = true; EXIT; } 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; } } _mongoc_monitor_legacy_write (client, command, database, collection, write_concern, server_stream, request_id); if (!mongoc_cluster_sendv_to_server ( &client->cluster, &rpc, server_stream, write_concern, error)) { result->failed = true; EXIT; } if (mongoc_write_concern_is_acknowledged (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, client->error_api_version, MONGOC_ERROR_COLLECTION_UPDATE_FAILED, offset); offset++; } _mongoc_monitor_legacy_write_succeeded (client, bson_get_monotonic_time () - started, command, gle, server_stream, request_id); if (gle) { bson_destroy (gle); gle = NULL; } started = bson_get_monotonic_time (); } } 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) { mongoc_cmd_parts_t parts; 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); bson_init (&cmd); 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_is_acknowledged (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; } if (command->flags.has_collation) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Cannot set collation for unacknowledged writes"); EXIT; } gLegacyWriteOps[command->type](command, client, server_stream, database, collection, write_concern, offset, result, error); EXIT; } if (command->flags.has_collation && server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "Collation is not supported by the selected server"); EXIT; } if (!command->n_documents || !bson_iter_init (&iter, command->documents) || !bson_iter_next (&iter)) { _empty_error (command, error); result->failed = true; EXIT; } again: has_more = false; i = 0; _mongoc_write_command_init (&cmd, command, collection, write_concern); /* 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 { BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); bson_iter_document (&iter, &len, &data); /* append array element like "0": { ... doc ... } */ key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str); /* 1 byte to specify document type, 1 byte for key's null terminator */ 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; } BSON_ASSERT (bson_init_static (&tmp, data, len)); 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; /* the current document is too large, continue to the next */ if (!bson_iter_next (&iter)) { GOTO (cleanup); } } else { mongoc_cmd_parts_init (&parts, database, MONGOC_QUERY_NONE, &cmd); parts.is_write_command = true; parts.assembled.operation_id = command->operation_id; ret = mongoc_cluster_run_command_monitored ( &client->cluster, &parts, server_stream, &reply, error); if (!ret) { result->failed = true; if (bson_empty (&reply)) { /* The command not only failed, * the roundtrip to the server failed and the node was disconnected */ result->must_stop = true; } } _mongoc_write_result_merge (result, command, &reply, offset); offset += i; bson_destroy (&reply); mongoc_cmd_parts_cleanup (&parts); } if (has_more && (ret || !command->flags.ordered) && !result->must_stop) { bson_reinit (&cmd); GOTO (again); } cleanup: bson_destroy (&cmd); 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 (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 { if (command->flags.bypass_document_validation != MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT) { bson_set_error ( &result->error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Cannot set bypassDocumentValidation for unacknowledged writes"); result->failed = true; EXIT; } if (command->flags.has_collation && server_stream->sd->max_wire_version < WIRE_VERSION_COLLATION) { bson_set_error (&result->error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Cannot set collation for unacknowledged writes"); result->failed = true; EXIT; } 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, mongoc_error_domain_t domain, int32_t code, uint32_t offset) { bson_t holder, write_errors, child; bson_iter_t iter; BSON_ASSERT (code > 0); if (!result->error.domain) { bson_set_error (&result->error, domain, (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 */ int32_t error_api_version, 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; mongoc_error_domain_t domain; ENTRY; BSON_ASSERT (result); BSON_ASSERT (reply); domain = error_api_version >= MONGOC_ERROR_API_VERSION_2 ? MONGOC_ERROR_SERVER : MONGOC_ERROR_COLLECTION; 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 (_is_duplicate_key_error (code)) { code = MONGOC_ERROR_DUPLICATE_KEY; } 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, domain, 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, /* IN */ int32_t error_api_version, /* IN */ const mongoc_write_concern_t *wc, /* IN */ mongoc_error_domain_t err_domain_override, /* IN */ bson_t *bson, /* OUT */ bson_error_t *error) /* OUT */ { mongoc_error_domain_t domain; ENTRY; BSON_ASSERT (result); if (error_api_version >= MONGOC_ERROR_API_VERSION_2) { domain = MONGOC_ERROR_SERVER; } else if (err_domain_override) { domain = err_domain_override; } else if (result->error.domain) { domain = (mongoc_error_domain_t) result->error.domain; } else { domain = MONGOC_ERROR_COLLECTION; } if (bson && mongoc_write_concern_is_acknowledged (wc)) { 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, domain, "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.3.4/src/libmongoc/src/mongoc/mongoc-write-concern-private.h0000664000175000017500000000325313210321137025471 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_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_; /* deprecated */ int8_t journal; int32_t w; int32_t wtimeout; char *wtag; bool frozen; bson_t compiled; bson_t compiled_gle; bool is_default; }; mongoc_write_concern_t * _mongoc_write_concern_new_from_iter (bson_iter_t *iter); bool _mongoc_write_concern_iter_is_valid (bson_iter_t *iter); 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_validate (const mongoc_write_concern_t *write_concern, bson_error_t *error); bool _mongoc_parse_wc_err (const bson_t *doc, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_WRITE_CONCERN_PRIVATE_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-write-concern.c0000664000175000017500000004414713210321137024023 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-error.h" #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; write_concern->is_default = true; 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); ret->is_default = write_concern->is_default; } 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_; write_concern->is_default = false; } } bool mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); return (write_concern->journal == true); } bool mongoc_write_concern_journal_is_set ( const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); return (write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT); } /** * 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; write_concern->is_default = false; } } 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; if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) { write_concern->is_default = false; } } } 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; write_concern->is_default = false; } } 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; write_concern->is_default = false; 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; write_concern->is_default = false; } } /** * 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_is_default: * @write_concern: A mongoc_write_concern_t. * * Returns is_default, which is true when write_concern has not been modified. * */ bool mongoc_write_concern_is_default (const mongoc_write_concern_t *write_concern) { return !write_concern || write_concern->is_default; } /** * 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 { 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_is_acknowledged: * @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_is_acknowledged ( 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)) || write_concern->fsync_ == true || mongoc_write_concern_get_journal (write_concern)); } return true; } /** * 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 ((write_concern->fsync_ == true || 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; } bool _mongoc_write_concern_validate (const mongoc_write_concern_t *write_concern, bson_error_t *error) { if (write_concern && !mongoc_write_concern_is_valid (write_concern)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Invalid mongoc_write_concern_t"); return false; } return true; } /** * _mongoc_parse_wc_err: * @doc: (in): A bson document. * @error: (out): A bson_error_t. * * Parses a document, usually a server reply, * looking for a writeConcernError. Returns true if * there is a writeConcernError, false otherwise. */ bool _mongoc_parse_wc_err (const bson_t *doc, bson_error_t *error) { bson_iter_t iter; bson_iter_t inner; if (bson_iter_init_find (&iter, doc, "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); return true; } return false; } /** * mongoc_write_concern_append: * @write_concern: (in): A mongoc_write_concern_t. * @command: (out): A pointer to a bson document. * * Appends a write_concern document to a command, to send to * a server. * * Returns true on success, false on failure. * */ bool mongoc_write_concern_append (mongoc_write_concern_t *write_concern, bson_t *command) { if (!mongoc_write_concern_is_valid (write_concern)) { MONGOC_ERROR ("Invalid writeConcern passed into " "mongoc_write_concern_append."); return false; } if (!bson_append_document (command, "writeConcern", 12, _mongoc_write_concern_get_bson (write_concern))) { MONGOC_ERROR ("Could not append writeConcern to command."); return false; } return true; } /** * _mongoc_write_concern_new_from_iter: * * Create a new mongoc_write_concern_t from an iterator positioned on * a "writeConcern" document. * * 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_from_iter (bson_iter_t *iter) { bson_iter_t inner; mongoc_write_concern_t *write_concern; BSON_ASSERT (iter); 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; BSON_ASSERT (bson_iter_recurse (iter, &inner)); while (bson_iter_next (&inner)) { if (BSON_ITER_IS_KEY (&inner, "w")) { if (BSON_ITER_HOLDS_INT32 (&inner)) { write_concern->w = bson_iter_int32 (&inner); } else if (BSON_ITER_HOLDS_UTF8 (&inner)) { if (!strcmp (bson_iter_utf8 (&inner, NULL), "majority")) { write_concern->w = MONGOC_WRITE_CONCERN_W_MAJORITY; } else { write_concern->w = MONGOC_WRITE_CONCERN_W_TAG; write_concern->wtag = bson_iter_dup_utf8 (&inner, NULL); } } } else if (BSON_ITER_IS_KEY (&inner, "fsync") && BSON_ITER_HOLDS_BOOL (&inner)) { write_concern->fsync_ = bson_iter_bool (&inner); } else if (BSON_ITER_IS_KEY (&inner, "j") && BSON_ITER_HOLDS_BOOL (&inner)) { write_concern->journal = bson_iter_bool (&inner); } else if (BSON_ITER_IS_KEY (&inner, "wtimeout") && BSON_ITER_HOLDS_INT32 (&inner)) { write_concern->wtimeout = bson_iter_bool (&inner); } } return write_concern; } /** * _mongoc_write_concern_iter_is_valid: * @iter: (in): A bson_iter_t positioned on a "writeConcern" BSON document. * * 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_iter_is_valid (bson_iter_t *iter) { bson_iter_t inner; bool has_fsync = false; bool w0 = false; bool j = false; BSON_ASSERT (iter); BSON_ASSERT (bson_iter_recurse (iter, &inner)); while (bson_iter_next (&inner)) { if (BSON_ITER_IS_KEY (&inner, "fsync")) { if (!BSON_ITER_HOLDS_BOOL (&inner)) { return false; } has_fsync = bson_iter_bool (&inner); } else if (BSON_ITER_IS_KEY (&inner, "w")) { if (BSON_ITER_HOLDS_INT32 (&inner)) { if (bson_iter_int32 (&inner) == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || bson_iter_int32 (&inner) == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED) { w0 = true; } } else if (!(BSON_ITER_HOLDS_UTF8 (&inner))) { return false; } } else if (BSON_ITER_IS_KEY (&inner, "j")) { if (!BSON_ITER_HOLDS_BOOL (&inner)) { return false; } j = bson_iter_bool (&inner); } else if (BSON_ITER_IS_KEY (&inner, "wtimeout")) { if (!BSON_ITER_HOLDS_INT32 (&inner) || bson_iter_int32 (&inner) < 0) { return false; } } } if ((has_fsync || j) && w0) { return false; } return true; } mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc-write-concern.h0000664000175000017500000000670013210321137024021 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 #include "mongoc-macros.h" 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_EXPORT (mongoc_write_concern_t *) mongoc_write_concern_new (void); MONGOC_EXPORT (mongoc_write_concern_t *) mongoc_write_concern_copy (const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (void) mongoc_write_concern_destroy (mongoc_write_concern_t *write_concern); MONGOC_EXPORT (bool) mongoc_write_concern_get_fsync (const mongoc_write_concern_t *write_concern) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (void) mongoc_write_concern_set_fsync (mongoc_write_concern_t *write_concern, bool fsync_) BSON_GNUC_DEPRECATED; MONGOC_EXPORT (bool) mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (bool) mongoc_write_concern_journal_is_set ( const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (void) mongoc_write_concern_set_journal (mongoc_write_concern_t *write_concern, bool journal); MONGOC_EXPORT (int32_t) mongoc_write_concern_get_w (const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (void) mongoc_write_concern_set_w (mongoc_write_concern_t *write_concern, int32_t w); MONGOC_EXPORT (const char *) mongoc_write_concern_get_wtag (const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (void) mongoc_write_concern_set_wtag (mongoc_write_concern_t *write_concern, const char *tag); MONGOC_EXPORT (int32_t) mongoc_write_concern_get_wtimeout (const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (void) mongoc_write_concern_set_wtimeout (mongoc_write_concern_t *write_concern, int32_t wtimeout_msec); MONGOC_EXPORT (bool) mongoc_write_concern_get_wmajority ( const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (void) mongoc_write_concern_set_wmajority (mongoc_write_concern_t *write_concern, int32_t wtimeout_msec); MONGOC_EXPORT (bool) mongoc_write_concern_is_acknowledged ( const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (bool) mongoc_write_concern_is_valid (const mongoc_write_concern_t *write_concern); MONGOC_EXPORT (bool) mongoc_write_concern_append (mongoc_write_concern_t *write_concern, bson_t *doc); MONGOC_EXPORT (bool) mongoc_write_concern_is_default (const mongoc_write_concern_t *write_concern); BSON_END_DECLS #endif /* MONGOC_WRITE_CONCERN_H */ mongodb-1.3.4/src/libmongoc/src/mongoc/mongoc.h0000664000175000017500000000336313210321137021246 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-macros.h" #include "mongoc-apm.h" #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-handshake.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.3.4/src/libmongoc/src/mongoc/op-compressed.def0000664000175000017500000000037313210321137023051 0ustar jmikolajmikolaRPC( compressed, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) INT32_FIELD(original_opcode) INT32_FIELD(uncompressed_size) UINT8_FIELD(compressor_id) RAW_BUFFER_FIELD(compressed_message) ) mongodb-1.3.4/src/libmongoc/src/mongoc/op-delete.def0000664000175000017500000000031613210321137022144 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.3.4/src/libmongoc/src/mongoc/op-get-more.def0000664000175000017500000000032613210321137022422 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.3.4/src/libmongoc/src/mongoc/op-header.def0000664000175000017500000000016313210321137022132 0ustar jmikolajmikolaRPC( header, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) ) mongodb-1.3.4/src/libmongoc/src/mongoc/op-insert.def0000664000175000017500000000030213210321137022201 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.3.4/src/libmongoc/src/mongoc/op-kill-cursors.def0000664000175000017500000000026513210321137023336 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.3.4/src/libmongoc/src/mongoc/op-msg.def0000664000175000017500000000020513210321137021465 0ustar jmikolajmikolaRPC( msg, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) CSTRING_FIELD(msg) ) mongodb-1.3.4/src/libmongoc/src/mongoc/op-query.def0000664000175000017500000000041613210321137022050 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.3.4/src/libmongoc/src/mongoc/op-reply-header.def0000664000175000017500000000033213210321137023261 0ustar jmikolajmikolaRPC( reply_header, 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) ) mongodb-1.3.4/src/libmongoc/src/mongoc/op-reply.def0000664000175000017500000000036113210321137022035 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.3.4/src/libmongoc/src/mongoc/op-update.def0000664000175000017500000000034313210321137022164 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.3.4/src/libmongoc/src/mongoc/utlist.h0000664000175000017500000012571113210321137021312 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 /* * 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; \ BSON_ASSERT (head != NULL); \ BSON_ASSERT (el != NULL); \ BSON_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; \ BSON_ASSERT (head != NULL); \ BSON_ASSERT (el != NULL); \ BSON_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 { \ BSON_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 { \ BSON_ASSERT (head != NULL); \ BSON_ASSERT (el != NULL); \ BSON_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 { \ BSON_ASSERT (head != NULL); \ BSON_ASSERT (el != NULL); \ BSON_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 { \ BSON_ASSERT (head != NULL); \ BSON_ASSERT (el != NULL); \ BSON_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 { \ BSON_ASSERT (head != NULL); \ BSON_ASSERT (el != NULL); \ BSON_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.3.4/src/libmongoc/VERSION_CURRENT0000664000175000017500000000000513210321137020002 0ustar jmikolajmikola1.8.2mongodb-1.3.4/src/libmongoc/VERSION_RELEASED0000664000175000017500000000000513210321137020044 0ustar jmikolajmikola1.8.2mongodb-1.3.4/src/bson-encode.c0000664000175000017500000004762313210321137016140 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "php_phongo.h" #include "php_bson.h" #include "phongo_compat.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" /* Determines whether the argument should be serialized as a BSON array or * document. IS_ARRAY is returned if the argument's keys are a sequence of * integers starting at zero; otherwise, IS_OBJECT is returned. */ static 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; } /* }}} */ /* Appends the array or object argument to the BSON document. If the object is * an instance of MongoDB\BSON\Serializable, the return value of bsonSerialize() * will be appended as an embedded document. Other MongoDB\BSON\Type instances * will be appended as the appropriate BSON type. Other array or object values * will be appended as an embedded document. */ static void php_phongo_bson_append_object(bson_t *bson, php_phongo_bson_flags_t flags, const char *key, long key_len, zval *object TSRMLS_DC) /* {{{ */ { if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_cursorid_ce TSRMLS_CC)) { bson_append_int64(bson, key, key_len, Z_CURSORID_OBJ_P(object)->id); return; } 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; #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 or bsonSerialize() threw an * exception. Either way, there is nothing else to do. */ 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; } /* 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 php_phongo_zval_to_bson(&obj_data, flags, &child, NULL TSRMLS_CC); #else php_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 php_phongo_zval_to_bson(&obj_data, flags, &child, NULL TSRMLS_CC); #else php_phongo_zval_to_bson(obj_data, flags, &child, NULL TSRMLS_CC); #endif bson_append_array_end(bson, &child); } zval_ptr_dtor(&obj_data); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_objectid_ce TSRMLS_CC)) { bson_oid_t oid; php_phongo_objectid_t *intern = Z_OBJECTID_OBJ_P(object); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding ObjectId"); bson_oid_init_from_string(&oid, intern->oid); bson_append_oid(bson, key, key_len, &oid); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_utcdatetime_ce TSRMLS_CC)) { php_phongo_utcdatetime_t *intern = Z_UTCDATETIME_OBJ_P(object); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding UTCDateTime"); bson_append_date_time(bson, key, key_len, intern->milliseconds); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_binary_ce TSRMLS_CC)) { php_phongo_binary_t *intern = Z_BINARY_OBJ_P(object); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Binary"); bson_append_binary(bson, key, key_len, intern->type, (const uint8_t *)intern->data, (uint32_t)intern->data_len); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_decimal128_ce TSRMLS_CC)) { php_phongo_decimal128_t *intern = Z_DECIMAL128_OBJ_P(object); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Decimal128"); bson_append_decimal128(bson, key, key_len, &intern->decimal); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_regex_ce TSRMLS_CC)) { php_phongo_regex_t *intern = Z_REGEX_OBJ_P(object); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Regex"); bson_append_regex(bson, key, key_len, intern->pattern, intern->flags); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_javascript_ce TSRMLS_CC)) { php_phongo_javascript_t *intern = Z_JAVASCRIPT_OBJ_P(object); if (intern->scope) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript with scope"); bson_append_code_with_scope(bson, key, key_len, intern->code, intern->scope); } else { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript without scope"); bson_append_code(bson, key, key_len, intern->code); } return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_timestamp_ce TSRMLS_CC)) { php_phongo_timestamp_t *intern = Z_TIMESTAMP_OBJ_P(object); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Timestamp"); bson_append_timestamp(bson, key, key_len, intern->timestamp, intern->increment); 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; } 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)); return; } else { bson_t child; mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding document"); bson_append_document_begin(bson, key, key_len, &child); php_phongo_zval_to_bson(object, flags, &child, NULL TSRMLS_CC); bson_append_document_end(bson, &child); } } /* }}} */ /* Appends the zval argument to the BSON document. If the argument is an object, * or an array that should be serialized as an embedded document, this function * will defer to php_phongo_bson_append_object(). */ static void php_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, "Detected invalid UTF-8 for fieldname \"%s\": %s", key, 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_GET_APPLY_COUNT(tmp_ht) > 0) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected recursion for fieldname \"%s\"", key); break; } if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { ZEND_HASH_INC_APPLY_COUNT(tmp_ht); } bson_append_array_begin(bson, key, key_len, &child); php_phongo_zval_to_bson(entry, flags, &child, NULL TSRMLS_CC); bson_append_array_end(bson, &child); if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); } break; } /* break intentionally omitted */ case IS_OBJECT: { HashTable *tmp_ht = HASH_OF(entry); if (tmp_ht && ZEND_HASH_GET_APPLY_COUNT(tmp_ht) > 0) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected recursion for fieldname \"%s\"", key); break; } if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { ZEND_HASH_INC_APPLY_COUNT(tmp_ht); } php_phongo_bson_append_object(bson, flags, key, key_len, entry TSRMLS_CC); if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) { ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); } break; } #if PHP_VERSION_ID >= 70000 case IS_INDIRECT: php_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, "Detected unsupported PHP type for fieldname \"%s\": %d (%s)", key, Z_TYPE_P(entry), zend_get_type_by_const(Z_TYPE_P(entry))); } } /* }}} */ /* Converts the array or object argument to a BSON document. If the object is an * instance of MongoDB\BSON\Serializable, the return value of bsonSerialize() * will be used. */ void php_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; /* If the object is an instance of MongoDB\BSON\Persistable, we will need to * inject the PHP class name as a BSON key and ignore any existing key in * the return value of bsonSerialize(). */ bool skip_odm_field = false; ZVAL_UNDEF(&obj_data); 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 or bsonSerialize() threw an * exception. Either way, there is nothing else to do. */ 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))) { #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 ) ); goto cleanup; } #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); #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)); #endif /* Ensure that we ignore an existing key with the same name * if one exists in the bsonSerialize() return value. */ skip_odm_field = true; } break; } if (instanceof_function(Z_OBJCE_P(data), php_phongo_type_ce TSRMLS_CC)) { 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)); return; } 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 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) { if (string_key) { if (ht_data_from_properties) { /* Skip protected and private properties */ if (ZSTR_VAL(string_key)[0] == '\0' && ZSTR_LEN(string_key) > 0) { continue; } } if (strlen(ZSTR_VAL(string_key)) != ZSTR_LEN(string_key)) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key)); goto cleanup; } if (skip_odm_field && !strcmp(ZSTR_VAL(string_key), PHONGO_ODM_FIELD_NAME)) { continue; } if (flags & PHONGO_BSON_ADD_ID) { if (!strcmp(ZSTR_VAL(string_key), "_id")) { flags &= ~PHONGO_BSON_ADD_ID; } } } /* 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); } php_phongo_bson_append(bson, flags & ~PHONGO_BSON_ADD_ID, ZSTR_VAL(string_key), strlen(ZSTR_VAL(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) { /* Skip protected and private properties */ if (string_key[0] == '\0' && string_key_len > 1) { continue; } } if (strlen(string_key) != string_key_len - 1) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "BSON keys cannot contain null bytes. Unexpected null byte after \"%s\".", ZSTR_VAL(string_key)); goto cleanup; } if (skip_odm_field && !strcmp(string_key, PHONGO_ODM_FIELD_NAME)) { continue; } if (flags & PHONGO_BSON_ADD_ID) { if (!strcmp(string_key, "_id")) { 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); } php_phongo_bson_append(bson, flags & ~PHONGO_BSON_ADD_ID, string_key, strlen(string_key), *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 && bson_out) { bson_iter_t iter; *bson_out = bson_new(); if (bson_iter_init_find(&iter, bson, "_id") && !bson_append_iter(*bson_out, NULL, 0, &iter)) { /* This should not be able to happen since we are copying from * within a valid bson_t. */ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Error copying \"_id\" field from encoded document"); goto cleanup; } } cleanup: if (!Z_ISUNDEF(obj_data)) { zval_ptr_dtor(&obj_data); } } /* }}} */ /* * 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.3.4/src/bson.c0000664000175000017500000007024713210321137014703 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "php_phongo.h" #include "php_bson.h" #include "phongo_compat.h" #include "php_array_api.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "PHONGO-BSON" #define PHONGO_IS_CLASS_INSTANTIATABLE(ce) \ (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) #if PHP_VERSION_ID >= 70000 # define PHONGO_BSON_STATE_ZCHILD(state) (&((php_phongo_bson_state *)(state))->zchild) #else # define PHONGO_BSON_STATE_ZCHILD(state) (((php_phongo_bson_state *)(state))->zchild) #endif /* Forward declarations */ static bool php_phongo_bson_visit_document(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_document, void *data); static bool php_phongo_bson_visit_array(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_document, void *data); static void php_phongo_bson_visit_corrupt(const bson_iter_t *iter ARG_UNUSED, void *data ARG_UNUSED) /* {{{ */ { mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Corrupt BSON data detected!"); } /* }}} */ static void php_phongo_bson_visit_unsupported_type(const bson_iter_t *iter ARG_UNUSED, const char *key, uint32_t v_type_code, void *data ARG_UNUSED) /* {{{ */ { TSRMLS_FETCH(); phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected unknown BSON type 0x%02hhx for fieldname \"%s\". Are you using the latest driver?", v_type_code, key); } /* }}} */ static bool php_phongo_bson_visit_double(const bson_iter_t *iter ARG_UNUSED, const char *key, double v_double, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_double(retval, v_double); } else { add_assoc_double(retval, key, v_double); } return false; } /* }}} */ static 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) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); if (((php_phongo_bson_state *)data)->is_visiting_array) { ADD_NEXT_INDEX_STRINGL(retval, v_utf8, v_utf8_len); } else { ADD_ASSOC_STRING_EX(retval, key, strlen(key), v_utf8, v_utf8_len); } return false; } /* }}} */ static 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) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); 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_release(zs_classname); #else zend_class_entry *found_ce = zend_fetch_class((const 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { ADD_ASSOC_ZVAL(retval, key, &zchild); } #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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif } return false; } /* }}} */ static bool php_phongo_bson_visit_undefined(const bson_iter_t *iter, const char *key, void *data) /* {{{ */ { mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Detected unsupported BSON type 0x06 (undefined) for fieldname \"%s\"", key); return false; } /* }}} */ static bool php_phongo_bson_visit_oid(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_oid_t *v_oid, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_objectid_new_from_oid(&zchild, v_oid TSRMLS_CC); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_bool(const bson_iter_t *iter ARG_UNUSED, const char *key, bool v_bool, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_bool(retval, v_bool); } else { add_assoc_bool(retval, key, v_bool); } return false; } /* }}} */ static bool php_phongo_bson_visit_date_time(const bson_iter_t *iter ARG_UNUSED, const char *key, int64_t msec_since_epoch, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_utcdatetime_from_epoch(&zchild, msec_since_epoch TSRMLS_CC); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_decimal128(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_decimal128_t *decimal, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_decimal128(&zchild, decimal TSRMLS_CC); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { ADD_ASSOC_ZVAL(retval, key, &zchild); } #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); php_phongo_new_decimal128(zchild, decimal TSRMLS_CC); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_null(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_null(retval); } else { add_assoc_null(retval, key); } return false; } /* }}} */ static 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) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_regex_from_regex_and_options(&zchild, v_regex, v_options TSRMLS_CC); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_symbol(const bson_iter_t *iter, const char *key, size_t symbol_len, const char *symbol, void *data) /* {{{ */ { mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Detected unsupported BSON type 0x0E (symbol) for fieldname \"%s\"", key); return false; } /* }}} */ static 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) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_javascript_from_javascript(1, &zchild, v_code, v_code_len TSRMLS_CC); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_dbpointer(const bson_iter_t *iter, const char *key, size_t collection_len, const char *collection, const bson_oid_t *oid, void *data) /* {{{ */ { mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Detected unsupported BSON type 0x0C (DBPointer) for fieldname \"%s\"", key); return false; } /* }}} */ static 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) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_int32(const bson_iter_t *iter ARG_UNUSED, const char *key, int32_t v_int32, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_long(retval, v_int32); } else { add_assoc_long(retval, key, v_int32); } return false; } /* }}} */ static 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) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_timestamp_from_increment_and_timestamp(&zchild, v_increment, v_timestamp TSRMLS_CC); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_int64(const bson_iter_t *iter ARG_UNUSED, const char *key, int64_t v_int64, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if SIZEOF_PHONGO_LONG == 4 TSRMLS_FETCH(); #endif if (((php_phongo_bson_state *)data)->is_visiting_array) { ADD_NEXT_INDEX_INT64(retval, v_int64); } else { ADD_ASSOC_INT64(retval, key, v_int64); } return false; } /* }}} */ static bool php_phongo_bson_visit_maxkey(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; object_init_ex(&zchild, php_phongo_maxkey_ce); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { ADD_ASSOC_ZVAL(retval, key, &zchild); } #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); object_init_ex(zchild, php_phongo_maxkey_ce); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { ADD_ASSOC_ZVAL(retval, key, zchild); } #endif return false; } /* }}} */ static bool php_phongo_bson_visit_minkey(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); #if PHP_VERSION_ID >= 70000 zval zchild; object_init_ex(&zchild, php_phongo_minkey_ce); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &zchild); } else { ADD_ASSOC_ZVAL(retval, key, &zchild); } #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); object_init_ex(zchild, php_phongo_minkey_ce); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, zchild); } else { 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, 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, php_phongo_bson_visit_dbpointer, php_phongo_bson_visit_code, 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, php_phongo_bson_visit_unsupported_type, php_phongo_bson_visit_decimal128, { NULL } }; static bool php_phongo_bson_visit_document(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_document, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); 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 if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, &state.zchild); } #else if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, state.zchild); } #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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &obj); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, obj); } else { ADD_ASSOC_ZVAL(retval, key, obj); } zval_ptr_dtor(&state.zchild); #endif break; } case PHONGO_TYPEMAP_NATIVE_OBJECT: default: #if PHP_VERSION_ID >= 70000 convert_to_object(&state.zchild); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, &state.zchild); } #else convert_to_object(state.zchild); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, state.zchild); } #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; } /* }}} */ static bool php_phongo_bson_visit_array(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_array, void *data) /* {{{ */ { zval *retval = PHONGO_BSON_STATE_ZCHILD(data); 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; /* Note that we are visiting an array, so element visitors know to use * add_next_index() (i.e. disregard BSON keys) instead of add_assoc() * when building the PHP array. */ state.is_visiting_array = true; #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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &obj); } else { 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); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, obj); } else { ADD_ASSOC_ZVAL(retval, key, obj); } zval_ptr_dtor(&state.zchild); #endif break; } case PHONGO_TYPEMAP_NATIVE_OBJECT: #if PHP_VERSION_ID >= 70000 convert_to_object(&state.zchild); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, &state.zchild); } #else convert_to_object(state.zchild); if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, state.zchild); } #endif break; case PHONGO_TYPEMAP_NATIVE_ARRAY: default: #if PHP_VERSION_ID >= 70000 if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, &state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, &state.zchild); } #else if (((php_phongo_bson_state *)data)->is_visiting_array) { add_next_index_zval(retval, state.zchild); } else { ADD_ASSOC_ZVAL(retval, key, state.zchild); } #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; } /* }}} */ /* Converts a BSON document to a PHP value using the default typemap. */ #if PHP_VERSION_ID >= 70000 bool php_phongo_bson_to_zval(const unsigned char *data, int data_len, zval *zv) /* {{{ */ #else bool php_phongo_bson_to_zval(const unsigned char *data, int data_len, zval **zv) #endif { bool retval; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; retval = php_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; } /* }}} */ /* Converts a BSON document to a PHP value according to the typemap specified in * the state argument. * * On success, the result will be set on the state argument and true will be * returned. On error, an exception will have been thrown and false will be * returned. * * Note: the result zval in the state argument will always be initialized for * PHP 5.x so that the caller may always zval_ptr_dtor() it. The zval is left * as-is on PHP 7; however, it should have the type undefined if the state * was initialized to zero. */ bool php_phongo_bson_to_zval_ex(const unsigned char *data, int data_len, php_phongo_bson_state *state) /* {{{ */ { bson_reader_t *reader = NULL; bson_iter_t iter; const bson_t *b; bool eof = false; bool retval = 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"); goto cleanup; } if (!bson_iter_init(&iter, b)) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not initialize BSON iterator"); goto cleanup; } /* 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. If an exception has * been thrown already (due to an unsupported BSON type for example, * don't overwrite with a generic exception message. */ if (!EG(exception)) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Detected corrupt BSON data"); } goto cleanup; } /* 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 convert_to_object(&state->zchild); #else convert_to_object(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"); goto cleanup; } retval = true; cleanup: if (reader) { bson_reader_destroy(reader); } return retval; } /* }}} */ /* Fetches a zend_class_entry for the given class name and checks that it is * also instantiatable and implements a specified interface. Returns the class * on success; otherwise, NULL is returned and an exception is thrown. */ static zend_class_entry *php_phongo_bson_state_fetch_class(const char *classname, int classname_len, zend_class_entry *interface_ce TSRMLS_DC) /* {{{ */ { #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_release(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, interface_ce TSRMLS_CC)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Class %s does not implement %s", classname, ZSTR_VAL(interface_ce->name)); } else { return found_ce; } return NULL; } /* }}} */ /* Parses a BSON type (i.e. array, document, or root). On success, the type and * type_ce output arguments will be assigned and true will be returned; * otherwise, false is returned and an exception is thrown. */ static bool php_phongo_bson_state_parse_type(zval *options, const char *name, php_phongo_bson_typemap_types *type, zend_class_entry **type_ce TSRMLS_DC) /* {{{ */ { char *classname; int classname_len; zend_bool classname_free = 0; bool retval = true; classname = php_array_fetch_string(options, name, &classname_len, &classname_free); if (!classname_len) { goto cleanup; } 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 ((*type_ce = php_phongo_bson_state_fetch_class(classname, classname_len, php_phongo_unserializable_ce TSRMLS_CC))) { *type = PHONGO_TYPEMAP_CLASS; } else { retval = false; } } cleanup: if (classname_free) { str_efree(classname); } return retval; } /* }}} */ /* Applies the array argument to a typemap struct. Returns true on success; * otherwise, false is returned an an exception is thrown. */ bool php_phongo_bson_typemap_to_state(zval *typemap, php_phongo_bson_typemap *map TSRMLS_DC) /* {{{ */ { if (!typemap) { return true; } if (!php_phongo_bson_state_parse_type(typemap, "array", &map->array_type, &map->array TSRMLS_CC) || !php_phongo_bson_state_parse_type(typemap, "document", &map->document_type, &map->document TSRMLS_CC) || !php_phongo_bson_state_parse_type(typemap, "root", &map->root_type, &map->root TSRMLS_CC)) { /* Exception should already have been thrown */ return false; } return true; } /* }}} */ /* * 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.3.4/tests/apm/bug0950-001.phpt0000664000175000017500000000171713210321137017210 0ustar jmikolajmikola--TEST-- PHPC-950: Segfault killing cursor after subscriber HashTable is destroyed (no subscribers) --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); /* Exiting during iteration on a live cursor will result in * php_phongo_command_started() being invoked for the killCursor command after * RSHUTDOWN has already destroyed the subscriber HashTable */ foreach ($cursor as $data) { echo "Exiting during first iteration on cursor\n"; exit(0); } ?> ===DONE=== --EXPECT-- Exiting during first iteration on cursor mongodb-1.3.4/tests/apm/bug0950-002.phpt0000664000175000017500000000314713210321137017210 0ustar jmikolajmikola--TEST-- PHPC-950: Segfault killing cursor after subscriber HashTable is destroyed (one subscriber) --SKIPIF-- --FILE-- getCommandName()); } public function commandSucceeded(MongoDB\Driver\Monitoring\CommandSucceededEvent $event) { printf("- succeeded: %s\n", $event->getCommandName()); } public function commandFailed(MongoDB\Driver\Monitoring\CommandFailedEvent $event) { printf("- failed: %s\n", $event->getCommandName()); } } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); MongoDB\Driver\Monitoring\addSubscriber(new MySubscriber); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); /* Exiting during iteration on a live cursor will result in * php_phongo_command_started() being invoked for the killCursor command after * RSHUTDOWN has already destroyed the subscriber HashTable */ foreach ($cursor as $data) { echo "Exiting during first iteration on cursor\n"; exit(0); } ?> ===DONE=== --EXPECT-- - started: find - succeeded: find Exiting during first iteration on cursor mongodb-1.3.4/tests/apm/monitoring-addSubscriber-001.phpt0000664000175000017500000000207113210321137023046 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\addSubscriber(): Adding one subscriber --SKIPIF-- --FILE-- getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } CLEANUP( STANDALONE ); $query = new MongoDB\Driver\Query( [] ); $subscriber = new MySubscriber; echo "Before addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); echo "After addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- Before addSubscriber After addSubscriber - started: find mongodb-1.3.4/tests/apm/monitoring-addSubscriber-002.phpt0000664000175000017500000000275613210321137023061 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\addSubscriber(): Adding two subscribers --SKIPIF-- --FILE-- instanceName = $instanceName; } public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event ) { echo "- ({$this->instanceName}) - started: ", $event->getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } CLEANUP( STANDALONE ); $query = new MongoDB\Driver\Query( [] ); $subscriber1 = new MySubscriber( "ONE" ); $subscriber2 = new MySubscriber( "TWO" ); echo "Before addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber1 ); echo "After addSubscriber (ONE)\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber2 ); echo "After addSubscriber (TWO)\n"; $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- Before addSubscriber After addSubscriber (ONE) - (ONE) - started: find After addSubscriber (TWO) - (ONE) - started: find - (TWO) - started: find mongodb-1.3.4/tests/apm/monitoring-addSubscriber-003.phpt0000664000175000017500000000234213210321137023051 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\addSubscriber(): Adding one subscriber multiple times --SKIPIF-- --FILE-- getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } $query = new MongoDB\Driver\Query( [] ); $subscriber = new MySubscriber(); echo "Before addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); echo "After addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); echo "After addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- Before addSubscriber After addSubscriber - started: find After addSubscriber - started: find mongodb-1.3.4/tests/apm/monitoring-addSubscriber-004.phpt0000664000175000017500000000341613210321137023055 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\addSubscriber(): Adding three subscribers --SKIPIF-- --FILE-- instanceName = $instanceName; } public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event ) { echo "- ({$this->instanceName}) - started: ", $event->getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } CLEANUP( STANDALONE ); $query = new MongoDB\Driver\Query( [] ); $subscriber1 = new MySubscriber( "ONE" ); $subscriber2 = new MySubscriber( "TWO" ); $subscriber3 = new MySubscriber( "THR" ); echo "Before addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber1 ); echo "After addSubscriber (ONE)\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber2 ); echo "After addSubscriber (TWO)\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber3 ); echo "After addSubscriber (THR)\n"; $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- Before addSubscriber After addSubscriber (ONE) - (ONE) - started: find After addSubscriber (TWO) - (ONE) - started: find - (TWO) - started: find After addSubscriber (THR) - (ONE) - started: find - (TWO) - started: find - (THR) - started: find mongodb-1.3.4/tests/apm/monitoring-commandFailed-001.phpt0000664000175000017500000000453613210321137023025 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\CommandFailedEvent --SKIPIF-- --FILE-- getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { echo "failed: ", $event->getCommandName(), "\n"; echo "- getError() returns an object: ", is_object( $event->getError() ) ? 'yes' : 'no', "\n"; echo "- getError() returns an MongoDB\Driver\Exception\Exception object: ", $event->getError() instanceof MongoDB\Driver\Exception\Exception ? 'yes' : 'no', "\n"; echo "- getDurationMicros() returns an integer: ", is_integer( $event->getDurationMicros() ) ? 'yes' : 'no', "\n"; echo "- getDurationMicros() returns > 0: ", $event->getDurationMicros() > 0 ? 'yes' : 'no', "\n"; echo "- getCommandName() returns a string: ", is_string( $event->getCommandName() ) ? 'yes' : 'no', "\n"; echo "- getCommandName() returns '", $event->getCommandName(), "'\n"; echo "- getServer() returns an object: ", is_object( $event->getServer() ) ? 'yes' : 'no', "\n"; echo "- getServer() returns a Server object: ", $event->getServer() instanceof MongoDB\Driver\Server ? 'yes' : 'no', "\n"; echo "- getOperationId() returns a string: ", is_string( $event->getOperationId() ) ? 'yes' : 'no', "\n"; echo "- getRequestId() returns a string: ", is_string( $event->getRequestId() ) ? 'yes' : 'no', "\n"; } } $subscriber = new MySubscriber; MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); CLEANUP( STANDALONE ); ?> --EXPECT-- started: drop failed: drop - getError() returns an object: yes - getError() returns an MongoDB\Driver\Exception\Exception object: yes - getDurationMicros() returns an integer: yes - getDurationMicros() returns > 0: yes - getCommandName() returns a string: yes - getCommandName() returns 'drop' - getServer() returns an object: yes - getServer() returns a Server object: yes - getOperationId() returns a string: yes - getRequestId() returns a string: yes mongodb-1.3.4/tests/apm/monitoring-commandFailed-002.phpt0000664000175000017500000000244613210321137023024 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\CommandFailedEvent: requestId and operationId match --SKIPIF-- --FILE-- getCommandName(), "\n"; $this->startRequestId = $event->getRequestId(); $this->startOperationId = $event->getOperationId(); } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { echo "failed: ", $event->getCommandName(), "\n"; echo "- requestId matches: ", $this->startRequestId == $event->getRequestId() ? 'yes' : 'no', " \n"; echo "- operationId matches: ", $this->startOperationId == $event->getOperationId() ? 'yes' : 'no', " \n"; } } $query = new MongoDB\Driver\Query( [] ); $subscriber = new MySubscriber; MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); CLEANUP( STANDALONE ); ?> --EXPECT-- started: drop failed: drop - requestId matches: yes - operationId matches: yes mongodb-1.3.4/tests/apm/monitoring-commandStarted-001.phpt0000664000175000017500000000436613210321137023250 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\CommandStartedEvent --SKIPIF-- --FILE-- getCommandName(), "\n"; echo "- getCommand() returns an object: ", is_object( $event->getCommand() ) ? 'yes' : 'no', "\n"; echo "- getCommand() returns a stdClass object: ", $event->getCommand() instanceof stdClass ? 'yes' : 'no', "\n"; echo "- getDatabaseName() returns a string: ", is_string( $event->getDatabaseName() ) ? 'yes' : 'no', "\n"; echo "- getDatabaseName() returns '", $event->getDatabaseName(), "'\n"; echo "- getCommandName() returns a string: ", is_string( $event->getCommandName() ) ? 'yes' : 'no', "\n"; echo "- getCommandName() returns '", $event->getCommandName(), "'\n"; echo "- getServer() returns an object: ", is_object( $event->getServer() ) ? 'yes' : 'no', "\n"; echo "- getServer() returns a Server object: ", $event->getServer() instanceof MongoDB\Driver\Server ? 'yes' : 'no', "\n"; echo "- getOperationId() returns a string: ", is_string( $event->getOperationId() ) ? 'yes' : 'no', "\n"; echo "- getRequestId() returns a string: ", is_string( $event->getRequestId() ) ? 'yes' : 'no', "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } $query = new MongoDB\Driver\Query( [] ); $subscriber = new MySubscriber; MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- started: find - getCommand() returns an object: yes - getCommand() returns a stdClass object: yes - getDatabaseName() returns a string: yes - getDatabaseName() returns 'demo' - getCommandName() returns a string: yes - getCommandName() returns 'find' - getServer() returns an object: yes - getServer() returns a Server object: yes - getOperationId() returns a string: yes - getRequestId() returns a string: yes mongodb-1.3.4/tests/apm/monitoring-commandSucceeded-001.phpt0000664000175000017500000000453313210321137023522 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\CommandSucceededEvent --SKIPIF-- --FILE-- getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { echo "succeeded: ", $event->getCommandName(), "\n"; echo "- getReply() returns an object: ", is_object( $event->getReply() ) ? 'yes' : 'no', "\n"; echo "- getReply() returns a stdClass object: ", $event->getReply() instanceof stdClass ? 'yes' : 'no', "\n"; echo "- getDurationMicros() returns an integer: ", is_integer( $event->getDurationMicros() ) ? 'yes' : 'no', "\n"; echo "- getDurationMicros() returns > 0: ", $event->getDurationMicros() > 0 ? 'yes' : 'no', "\n"; echo "- getCommandName() returns a string: ", is_string( $event->getCommandName() ) ? 'yes' : 'no', "\n"; echo "- getCommandName() returns '", $event->getCommandName(), "'\n"; echo "- getServer() returns an object: ", is_object( $event->getServer() ) ? 'yes' : 'no', "\n"; echo "- getServer() returns a Server object: ", $event->getServer() instanceof MongoDB\Driver\Server ? 'yes' : 'no', "\n"; echo "- getOperationId() returns a string: ", is_string( $event->getOperationId() ) ? 'yes' : 'no', "\n"; echo "- getRequestId() returns a string: ", is_string( $event->getRequestId() ) ? 'yes' : 'no', "\n"; } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } $query = new MongoDB\Driver\Query( [] ); $subscriber = new MySubscriber; MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- started: find succeeded: find - getReply() returns an object: yes - getReply() returns a stdClass object: yes - getDurationMicros() returns an integer: yes - getDurationMicros() returns > 0: yes - getCommandName() returns a string: yes - getCommandName() returns 'find' - getServer() returns an object: yes - getServer() returns a Server object: yes - getOperationId() returns a string: yes - getRequestId() returns a string: yes mongodb-1.3.4/tests/apm/monitoring-commandSucceeded-002.phpt0000664000175000017500000000251313210321137023517 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\CommandSucceededEvent: requestId and operationId match --SKIPIF-- --FILE-- getCommandName(), "\n"; $this->startRequestId = $event->getRequestId(); $this->startOperationId = $event->getOperationId(); } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { echo "succeeded: ", $event->getCommandName(), "\n"; echo "- requestId matches: ", $this->startRequestId == $event->getRequestId() ? 'yes' : 'no', " \n"; echo "- operationId matches: ", $this->startOperationId == $event->getOperationId() ? 'yes' : 'no', " \n"; } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } $query = new MongoDB\Driver\Query( [] ); $subscriber = new MySubscriber; MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- started: find succeeded: find - requestId matches: yes - operationId matches: yes mongodb-1.3.4/tests/apm/monitoring-removeSubscriber-001.phpt0000664000175000017500000000232413210321137023614 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\removeSubscriber(): Removing the only subscriber --SKIPIF-- --FILE-- getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } $query = new MongoDB\Driver\Query( [] ); $subscriber = new MySubscriber; echo "Before addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber ); echo "After addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\removeSubscriber( $subscriber ); echo "After removeSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- Before addSubscriber After addSubscriber - started: find After removeSubscriber mongodb-1.3.4/tests/apm/monitoring-removeSubscriber-002.phpt0000664000175000017500000000326513210321137023622 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Monitoring\removeSubscriber(): Removing one of multiple subscribers --SKIPIF-- --FILE-- instanceName = $instanceName; } public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event ) { echo "- ({$this->instanceName}) - started: ", $event->getCommandName(), "\n"; } public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ) { } public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ) { } } $query = new MongoDB\Driver\Query( [] ); $subscriber1 = new MySubscriber( "ONE" ); $subscriber2 = new MySubscriber( "TWO" ); echo "Before addSubscriber\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber1 ); echo "After addSubscriber (ONE)\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\addSubscriber( $subscriber2 ); echo "After addSubscriber (TWO)\n"; $cursor = $m->executeQuery( "demo.test", $query ); MongoDB\Driver\Monitoring\removeSubscriber( $subscriber2 ); echo "After removeSubscriber (TWO)\n"; $cursor = $m->executeQuery( "demo.test", $query ); ?> --EXPECT-- Before addSubscriber After addSubscriber (ONE) - (ONE) - started: find After addSubscriber (TWO) - (ONE) - started: find - (TWO) - started: find After removeSubscriber (TWO) - (ONE) - started: find mongodb-1.3.4/tests/apm/overview.phpt0000664000175000017500000001040013210321137017452 0ustar jmikolajmikola--TEST-- PHPC-349: APM Specification --SKIPIF-- --FILE-- false ] ); $_id = $bw->insert( [ 'decimal' => $d ] ); $r = $m->executeBulkWrite( DATABASE_NAME . '.' . COLLECTION_NAME, $bw ); $query = new MongoDB\Driver\Query( [] ); $cursor = $m->executeQuery( DATABASE_NAME . '.' . COLLECTION_NAME, $query ); var_dump( $cursor->toArray() ); ?> --EXPECTF-- started: object(MongoDB\Driver\Monitoring\CommandStartedEvent)#%d (%d) { ["command"]=> object(stdClass)#%d (%d) { ["drop"]=> string(12) "apm_overview" } ["commandName"]=> string(4) "drop" ["databaseName"]=> string(6) "phongo" ["operationId"]=> string(%d) "%s" ["requestId"]=> string(%d) "%s" ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } failed: object(MongoDB\Driver\Monitoring\CommandFailedEvent)#%d (%d) { ["commandName"]=> string(4) "drop" ["durationMicros"]=> int(%d) ["error"]=> object(MongoDB\Driver\Exception\RuntimeException)#%d (%d) { ["message":protected]=> string(12) "ns not found" ["string":"Exception":private]=> string(0) "" ["code":protected]=> int(26) ["file":protected]=> string(%d) "%stests/%s" ["line":protected]=> int(%d) ["trace":"Exception":private]=> %a ["previous":"Exception":private]=> NULL } ["operationId"]=> string(%d) "%s" ["requestId"]=> string(%d) "%s" ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } started: object(MongoDB\Driver\Monitoring\CommandStartedEvent)#%d (%d) { ["command"]=> object(stdClass)#%d (%d) { ["insert"]=> string(12) "apm_overview" ["writeConcern"]=> object(stdClass)#%d (%d) { } ["ordered"]=> bool(false) ["documents"]=> array(%d) { [0]=> object(stdClass)#%d (%d) { ["decimal"]=> int(12345678) ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%s" } } } } ["commandName"]=> string(6) "insert" ["databaseName"]=> string(6) "phongo" ["operationId"]=> string(%d) "%s" ["requestId"]=> string(%d) "%s" ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } succeeded: object(MongoDB\Driver\Monitoring\CommandSucceededEvent)#%d (%d) { ["commandName"]=> string(6) "insert" ["durationMicros"]=> int(%d) ["operationId"]=> string(%d) "%s" ["reply"]=> object(stdClass)#%d (%d) { %a } ["requestId"]=> string(%d) "%s" ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } started: object(MongoDB\Driver\Monitoring\CommandStartedEvent)#%d (%d) { ["command"]=> object(stdClass)#%d (%d) { ["find"]=> string(12) "apm_overview" ["filter"]=> object(stdClass)#%d (%d) { } } ["commandName"]=> string(4) "find" ["databaseName"]=> string(6) "phongo" ["operationId"]=> string(%d) "%s" ["requestId"]=> string(%d) "%s" ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } succeeded: object(MongoDB\Driver\Monitoring\CommandSucceededEvent)#%d (%d) { ["commandName"]=> string(4) "find" ["durationMicros"]=> int(%d) ["operationId"]=> string(%d) "%s" ["reply"]=> object(stdClass)#%d (%d) { %a } ["requestId"]=> string(%d) "%s" ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } array(%d) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%s" } ["decimal"]=> int(12345678) } } mongodb-1.3.4/tests/bson-corpus/array-decodeError-001.phpt0000664000175000017500000000077113210321137023162 0ustar jmikolajmikola--TEST-- Array: Array length too long: eats outer terminator --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/array-decodeError-002.phpt0000664000175000017500000000076513210321137023166 0ustar jmikolajmikola--TEST-- Array: Array length too short: leaks terminator --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/array-decodeError-003.phpt0000664000175000017500000000100213210321137023150 0ustar jmikolajmikola--TEST-- Array: Invalid Array: bad string length in field --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/array-valid-001.phpt0000664000175000017500000000125413210321137022021 0ustar jmikolajmikola--TEST-- Array: Empty --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0d000000046100050000000000 {"a":[]} 0d000000046100050000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/array-valid-002.phpt0000664000175000017500000000141413210321137022020 0ustar jmikolajmikola--TEST-- Array: Single Element Array --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 140000000461000c0000001030000a0000000000 {"a":[{"$numberInt":"10"}]} 140000000461000c0000001030000a0000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/array-valid-003.phpt0000664000175000017500000000221113210321137022015 0ustar jmikolajmikola--TEST-- Array: Single Element Array with index set incorrectly --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate BSON -> Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($degenerateBson))), "\n"; // Degenerate BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($degenerateBson)), "\n"; ?> ===DONE=== --EXPECT-- 140000000461000c0000001030000a0000000000 {"a":[{"$numberInt":"10"}]} 140000000461000c0000001030000a0000000000 140000000461000c0000001030000a0000000000 {"a":[{"$numberInt":"10"}]} ===DONE===mongodb-1.3.4/tests/bson-corpus/array-valid-004.phpt0000664000175000017500000000221513210321137022022 0ustar jmikolajmikola--TEST-- Array: Single Element Array with index set incorrectly --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate BSON -> Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($degenerateBson))), "\n"; // Degenerate BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($degenerateBson)), "\n"; ?> ===DONE=== --EXPECT-- 140000000461000c0000001030000a0000000000 {"a":[{"$numberInt":"10"}]} 140000000461000c0000001030000a0000000000 140000000461000c0000001030000a0000000000 {"a":[{"$numberInt":"10"}]} ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-decodeError-001.phpt0000664000175000017500000000100013210321137023312 0ustar jmikolajmikola--TEST-- Binary type: Length longer than document --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-decodeError-002.phpt0000664000175000017500000000072413210321137023327 0ustar jmikolajmikola--TEST-- Binary type: Negative length --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-decodeError-003.phpt0000664000175000017500000000075513210321137023334 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x02 length too long --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-decodeError-004.phpt0000664000175000017500000000075613210321137023336 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x02 length too short --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-decodeError-005.phpt0000664000175000017500000000076113210321137023333 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x02 length negative one --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-001.phpt0000664000175000017500000000143313210321137022166 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x00 (Zero-length) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0d000000057800000000000000 {"x":{"$binary":{"base64":"","subType":"00"}}} 0d000000057800000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-002.phpt0000664000175000017500000000176213210321137022174 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x00 (Zero-length, keys reversed) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0d000000057800000000000000 {"x":{"$binary":{"base64":"","subType":"00"}}} 0d000000057800000000000000 0d000000057800000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-003.phpt0000664000175000017500000000144313210321137022171 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x00 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0f0000000578000200000000ffff00 {"x":{"$binary":{"base64":"\/\/8=","subType":"00"}}} 0f0000000578000200000000ffff00 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-004.phpt0000664000175000017500000000144313210321137022172 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x01 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0f0000000578000200000001ffff00 {"x":{"$binary":{"base64":"\/\/8=","subType":"01"}}} 0f0000000578000200000001ffff00 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-005.phpt0000664000175000017500000000147313210321137022176 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x02 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 13000000057800060000000202000000ffff00 {"x":{"$binary":{"base64":"\/\/8=","subType":"02"}}} 13000000057800060000000202000000ffff00 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-006.phpt0000664000175000017500000000163713210321137022201 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x03 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1d000000057800100000000373ffd26444b34c6990e8e7d1dfc035d400 {"x":{"$binary":{"base64":"c\/\/SZESzTGmQ6OfR38A11A==","subType":"03"}}} 1d000000057800100000000373ffd26444b34c6990e8e7d1dfc035d400 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-007.phpt0000664000175000017500000000163713210321137022202 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x04 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1d000000057800100000000473ffd26444b34c6990e8e7d1dfc035d400 {"x":{"$binary":{"base64":"c\/\/SZESzTGmQ6OfR38A11A==","subType":"04"}}} 1d000000057800100000000473ffd26444b34c6990e8e7d1dfc035d400 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-008.phpt0000664000175000017500000000163713210321137022203 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x05 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1d000000057800100000000573ffd26444b34c6990e8e7d1dfc035d400 {"x":{"$binary":{"base64":"c\/\/SZESzTGmQ6OfR38A11A==","subType":"05"}}} 1d000000057800100000000573ffd26444b34c6990e8e7d1dfc035d400 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-009.phpt0000664000175000017500000000144313210321137022177 0ustar jmikolajmikola--TEST-- Binary type: subtype 0x80 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0f0000000578000200000080ffff00 {"x":{"$binary":{"base64":"\/\/8=","subType":"80"}}} 0f0000000578000200000080ffff00 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-010.phpt0000664000175000017500000000160613210321137022170 0ustar jmikolajmikola--TEST-- Binary type: $type query operator (conflicts with legacy $binary form with $type field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1f000000037800170000000224747970650007000000737472696e67000000 {"x":{"$type":"string"}} 1f000000037800170000000224747970650007000000737472696e67000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/binary-valid-011.phpt0000664000175000017500000000156113210321137022171 0ustar jmikolajmikola--TEST-- Binary type: $type query operator (conflicts with legacy $binary form with $type field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000000378001000000010247479706500020000000000 {"x":{"$type":{"$numberInt":"2"}}} 180000000378001000000010247479706500020000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/boolean-decodeError-001.phpt0000664000175000017500000000072313210321137023460 0ustar jmikolajmikola--TEST-- Boolean: Invalid boolean value of 2 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/boolean-decodeError-002.phpt0000664000175000017500000000072413210321137023462 0ustar jmikolajmikola--TEST-- Boolean: Invalid boolean value of -1 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/boolean-valid-001.phpt0000664000175000017500000000123113210321137022315 0ustar jmikolajmikola--TEST-- Boolean: True --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 090000000862000100 {"b":true} 090000000862000100 ===DONE===mongodb-1.3.4/tests/bson-corpus/boolean-valid-002.phpt0000664000175000017500000000123413210321137022321 0ustar jmikolajmikola--TEST-- Boolean: False --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 090000000862000000 {"b":false} 090000000862000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code-decodeError-001.phpt0000664000175000017500000000076513210321137022761 0ustar jmikolajmikola--TEST-- Javascript Code: bad code string length: 0 (but no 0x00 either) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code-decodeError-002.phpt0000664000175000017500000000074113210321137022754 0ustar jmikolajmikola--TEST-- Javascript Code: bad code string length: -1 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code-decodeError-003.phpt0000664000175000017500000000076613210321137022764 0ustar jmikolajmikola--TEST-- Javascript Code: bad code string length: eats terminator --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code-decodeError-004.phpt0000664000175000017500000000100713210321137022752 0ustar jmikolajmikola--TEST-- Javascript Code: bad code string length: longer than rest of document --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code-decodeError-005.phpt0000664000175000017500000000076113210321137022761 0ustar jmikolajmikola--TEST-- Javascript Code: code string is not null-terminated --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code-decodeError-006.phpt0000664000175000017500000000075413210321137022764 0ustar jmikolajmikola--TEST-- Javascript Code: empty code string, but extra null --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code-decodeError-007.phpt0000664000175000017500000000073013210321137022757 0ustar jmikolajmikola--TEST-- Javascript Code: invalid UTF-8 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code-valid-001.phpt0000664000175000017500000000132313210321137021612 0ustar jmikolajmikola--TEST-- Javascript Code: Empty string --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0d0000000d6100010000000000 {"a":{"$code":""}} 0d0000000d6100010000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code-valid-002.phpt0000664000175000017500000000133713210321137021620 0ustar jmikolajmikola--TEST-- Javascript Code: Single character --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0e0000000d610002000000620000 {"a":{"$code":"b"}} 0e0000000d610002000000620000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code-valid-003.phpt0000664000175000017500000000146613210321137021624 0ustar jmikolajmikola--TEST-- Javascript Code: Multi-character --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000d61000d0000006162616261626162616261620000 {"a":{"$code":"abababababab"}} 190000000d61000d0000006162616261626162616261620000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code-valid-004.phpt0000664000175000017500000000153213210321137021617 0ustar jmikolajmikola--TEST-- Javascript Code: two-byte UTF-8 (é) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000261000d000000c3a9c3a9c3a9c3a9c3a9c3a90000 {"a":"\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9"} 190000000261000d000000c3a9c3a9c3a9c3a9c3a9c3a90000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code-valid-005.phpt0000664000175000017500000000150313210321137021616 0ustar jmikolajmikola--TEST-- Javascript Code: three-byte UTF-8 (☆) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000261000d000000e29886e29886e29886e298860000 {"a":"\u2606\u2606\u2606\u2606"} 190000000261000d000000e29886e29886e29886e298860000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code-valid-006.phpt0000664000175000017500000000146513210321137021626 0ustar jmikolajmikola--TEST-- Javascript Code: Embedded nulls --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000261000d0000006162006261620062616261620000 {"a":"ab\u0000bab\u0000babab"} 190000000261000d0000006162006261620062616261620000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-001.phpt0000664000175000017500000000103313210321137024465 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: field length zero --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-002.phpt0000664000175000017500000000103713210321137024472 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: field length negative --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-003.phpt0000664000175000017500000000102513210321137024470 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: field length too short (less than minimum size) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-004.phpt0000664000175000017500000000106213210321137024472 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: field length too short (truncates scope) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-005.phpt0000664000175000017500000000106113210321137024472 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: field length too long (clips outer doc) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-006.phpt0000664000175000017500000000106713210321137024501 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: field length too long (longer than outer doc) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-007.phpt0000664000175000017500000000105313210321137024475 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: bad code string: length too short --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-008.phpt0000664000175000017500000000107013210321137024475 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: bad code string: length too long (clips scope) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-009.phpt0000664000175000017500000000105213210321137024476 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: bad code string: negative length --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-010.phpt0000664000175000017500000000106313210321137024470 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: bad code string: length longer than field --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-decodeError-011.phpt0000664000175000017500000000107313210321137024472 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: bad scope doc (field has bad string length) --XFAIL-- Depends on PHPC-889 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-valid-001.phpt0000664000175000017500000000150113210321137023327 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: Empty code string, empty scope --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 160000000f61000e0000000100000000050000000000 {"a":{"$code":"","$scope":{}}} 160000000f61000e0000000100000000050000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-valid-002.phpt0000664000175000017500000000154513210321137023340 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: Non-empty code string, empty scope --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1a0000000f610012000000050000006162636400050000000000 {"a":{"$code":"abcd","$scope":{}}} 1a0000000f610012000000050000006162636400050000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-valid-003.phpt0000664000175000017500000000163613210321137023342 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: Empty code string, non-empty scope --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1d0000000f61001500000001000000000c000000107800010000000000 {"a":{"$code":"","$scope":{"x":{"$numberInt":"1"}}}} 1d0000000f61001500000001000000000c000000107800010000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-valid-004.phpt0000664000175000017500000000170513210321137023340 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: Non-empty code string and non-empty scope --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 210000000f6100190000000500000061626364000c000000107800010000000000 {"a":{"$code":"abcd","$scope":{"x":{"$numberInt":"1"}}}} 210000000f6100190000000500000061626364000c000000107800010000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/code_w_scope-valid-005.phpt0000664000175000017500000000173613210321137023345 0ustar jmikolajmikola--TEST-- Javascript Code with Scope: Unicode and embedded null in code string, empty scope --XFAIL-- Embedded null in code string is not supported in libbson (CDRIVER-1879) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1a0000000f61001200000005000000c3a9006400050000000000 {"a":{"$code":"\u00e9\u0000d","$scope":{}}} 1a0000000f61001200000005000000c3a9006400050000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/datetime-decodeError-001.phpt0000664000175000017500000000073013210321137023633 0ustar jmikolajmikola--TEST-- DateTime: datetime field truncated --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/datetime-valid-001.phpt0000664000175000017500000000216513210321137022501 0ustar jmikolajmikola--TEST-- DateTime: epoch --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000096100000000000000000000 {"a":{"$date":{"$numberLong":"0"}}} {"a":{"$date":"1970-01-01T00:00:00Z"}} 10000000096100000000000000000000 {"a":{"$date":"1970-01-01T00:00:00Z"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/datetime-valid-002.phpt0000664000175000017500000000223713210321137022502 0ustar jmikolajmikola--TEST-- DateTime: positive ms --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000096100c5d8d6cc3b01000000 {"a":{"$date":{"$numberLong":"1356351330501"}}} {"a":{"$date":"2012-12-24T12:15:30.501Z"}} 10000000096100c5d8d6cc3b01000000 {"a":{"$date":"2012-12-24T12:15:30.501Z"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/datetime-valid-003.phpt0000664000175000017500000000225513210321137022503 0ustar jmikolajmikola--TEST-- DateTime: negative --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000096100c33ce7b9bdffffff00 {"a":{"$date":{"$numberLong":"-284643869501"}}} {"a":{"$date":{"$numberLong":"-284643869501"}}} 10000000096100c33ce7b9bdffffff00 {"a":{"$date":{"$numberLong":"-284643869501"}}} ===DONE===mongodb-1.3.4/tests/bson-corpus/datetime-valid-004.phpt0000664000175000017500000000142013210321137022475 0ustar jmikolajmikola--TEST-- DateTime: Y10K --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1000000009610000dc1fd277e6000000 {"a":{"$date":{"$numberLong":"253402300800000"}}} 1000000009610000dc1fd277e6000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/dbref-valid-001.phpt0000664000175000017500000000205513210321137021765 0ustar jmikolajmikola--TEST-- DBRef: DBRef --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 37000000036462726566002b0000000224726566000b000000636f6c6c656374696f6e00072469640058921b3e6e32ab156a22b59e0000 {"dbref":{"$ref":"collection","$id":{"$oid":"58921b3e6e32ab156a22b59e"}}} 37000000036462726566002b0000000224726566000b000000636f6c6c656374696f6e00072469640058921b3e6e32ab156a22b59e0000 ===DONE===mongodb-1.3.4/tests/bson-corpus/dbref-valid-002.phpt0000664000175000017500000000223313210321137021764 0ustar jmikolajmikola--TEST-- DBRef: DBRef with database --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 4300000003646272656600370000000224726566000b000000636f6c6c656374696f6e00072469640058921b3e6e32ab156a22b59e0224646200030000006462000000 {"dbref":{"$ref":"collection","$id":{"$oid":"58921b3e6e32ab156a22b59e"},"$db":"db"}} 4300000003646272656600370000000224726566000b000000636f6c6c656374696f6e00072469640058921b3e6e32ab156a22b59e0224646200030000006462000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/dbref-valid-003.phpt0000664000175000017500000000231113210321137021762 0ustar jmikolajmikola--TEST-- DBRef: DBRef with database and additional fields --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 48000000036462726566003c0000000224726566000b000000636f6c6c656374696f6e0010246964002a00000002246462000300000064620002666f6f0004000000626172000000 {"dbref":{"$ref":"collection","$id":{"$numberInt":"42"},"$db":"db","foo":"bar"}} 48000000036462726566003c0000000224726566000b000000636f6c6c656374696f6e0010246964002a00000002246462000300000064620002666f6f0004000000626172000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/dbref-valid-004.phpt0000664000175000017500000000225413210321137021771 0ustar jmikolajmikola--TEST-- DBRef: DBRef with additional fields --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 4400000003646272656600380000000224726566000b000000636f6c6c656374696f6e00072469640058921b3e6e32ab156a22b59e02666f6f0004000000626172000000 {"dbref":{"$ref":"collection","$id":{"$oid":"58921b3e6e32ab156a22b59e"},"foo":"bar"}} 4400000003646272656600380000000224726566000b000000636f6c6c656374696f6e00072469640058921b3e6e32ab156a22b59e02666f6f0004000000626172000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/dbref-valid-005.phpt0000664000175000017500000000222613210321137021771 0ustar jmikolajmikola--TEST-- DBRef: Document with key names similar to those of a DBRef --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 3e0000000224726566000c0000006e6f742d612d646272656600072469640058921b3e6e32ab156a22b59e022462616e616e6100050000007065656c0000 {"$ref":"not-a-dbref","$id":{"$oid":"58921b3e6e32ab156a22b59e"},"$banana":"peel"} 3e0000000224726566000c0000006e6f742d612d646272656600072469640058921b3e6e32ab156a22b59e022462616e616e6100050000007065656c0000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-001.phpt0000664000175000017500000000146313210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: Special - Canonical NaN --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007c00 {"d":{"$numberDecimal":"NaN"}} 180000001364000000000000000000000000000000007c00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-002.phpt0000664000175000017500000000124713210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Special - Negative NaN --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000fc00 {"d":{"$numberDecimal":"NaN"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-003.phpt0000664000175000017500000000134313210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: Special - Negative NaN --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000fc00 {"d":{"$numberDecimal":"NaN"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-004.phpt0000664000175000017500000000125113210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: Special - Canonical SNaN --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007e00 {"d":{"$numberDecimal":"NaN"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-005.phpt0000664000175000017500000000125013210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: Special - Negative SNaN --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000fe00 {"d":{"$numberDecimal":"NaN"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-006.phpt0000664000175000017500000000125513210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: Special - NaN with a payload --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001200000000000000000000000000007e00 {"d":{"$numberDecimal":"NaN"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-007.phpt0000664000175000017500000000151313210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: Special - Canonical Positive Infinity --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007800 {"d":{"$numberDecimal":"Infinity"}} 180000001364000000000000000000000000000000007800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-008.phpt0000664000175000017500000000151513210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: Special - Canonical Negative Infinity --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000f800 {"d":{"$numberDecimal":"-Infinity"}} 18000000136400000000000000000000000000000000f800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-009.phpt0000664000175000017500000000127213210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: Special - Invalid representation treated as 0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000106c00 {"d":{"$numberDecimal":"0"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-010.phpt0000664000175000017500000000127513210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Special - Invalid representation treated as -0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400dcba9876543210deadbeef00000010ec00 {"d":{"$numberDecimal":"-0"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-011.phpt0000664000175000017500000000130213210321137022665 0ustar jmikolajmikola--TEST-- Decimal128: Special - Invalid representation treated as 0E3 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffffffffffffffffffffffff116c00 {"d":{"$numberDecimal":"0E+3"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-012.phpt0000664000175000017500000000161113210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: Regular - Adjusted Exponent Limit --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3cf22f00 {"d":{"$numberDecimal":"0.000001234567890123456789012345678901234"}} 18000000136400f2af967ed05c82de3297ff6fde3cf22f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-013.phpt0000664000175000017500000000147013210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Regular - Smallest --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400d204000000000000000000000000343000 {"d":{"$numberDecimal":"0.001234"}} 18000000136400d204000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-014.phpt0000664000175000017500000000152613210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: Regular - Smallest with Trailing Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640040ef5a07000000000000000000002a3000 {"d":{"$numberDecimal":"0.00123400000"}} 1800000013640040ef5a07000000000000000000002a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-015.phpt0000664000175000017500000000145113210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: Regular - 0.1 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640001000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.1"}} 1800000013640001000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-016.phpt0000664000175000017500000000161413210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: Regular - 0.1234567890123456789012345678901234 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3cfc2f00 {"d":{"$numberDecimal":"0.1234567890123456789012345678901234"}} 18000000136400f2af967ed05c82de3297ff6fde3cfc2f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-017.phpt0000664000175000017500000000144313210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: Regular - 0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-018.phpt0000664000175000017500000000144613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: Regular - -0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000040b000 {"d":{"$numberDecimal":"-0"}} 18000000136400000000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-019.phpt0000664000175000017500000000145413210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: Regular - -0.0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003eb000 {"d":{"$numberDecimal":"-0.0"}} 1800000013640000000000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-020.phpt0000664000175000017500000000144313210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: Regular - 2 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000200000000000000000000000000403000 {"d":{"$numberDecimal":"2"}} 180000001364000200000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-021.phpt0000664000175000017500000000145713210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: Regular - 2.000 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400d0070000000000000000000000003a3000 {"d":{"$numberDecimal":"2.000"}} 18000000136400d0070000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-022.phpt0000664000175000017500000000155313210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: Regular - Largest --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3c403000 {"d":{"$numberDecimal":"1234567890123456789012345678901234"}} 18000000136400f2af967ed05c82de3297ff6fde3c403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-023.phpt0000664000175000017500000000157413210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Tiniest --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff638e8d37c087adbe09ed010000 {"d":{"$numberDecimal":"9.999999999999999999999999999999999E-6143"}} 18000000136400ffffffff638e8d37c087adbe09ed010000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-024.phpt0000664000175000017500000000146513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Tiny --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000000000 {"d":{"$numberDecimal":"1E-6176"}} 180000001364000100000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-025.phpt0000664000175000017500000000150013210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Negative Tiny --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000008000 {"d":{"$numberDecimal":"-1E-6176"}} 180000001364000100000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-026.phpt0000664000175000017500000000160613210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Adjusted Exponent Limit --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3cf02f00 {"d":{"$numberDecimal":"1.234567890123456789012345678901234E-7"}} 18000000136400f2af967ed05c82de3297ff6fde3cf02f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-027.phpt0000664000175000017500000000147513210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Fractional --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640064000000000000000000000000002cb000 {"d":{"$numberDecimal":"-1.00E-8"}} 1800000013640064000000000000000000000000002cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-028.phpt0000664000175000017500000000150013210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - 0 with Exponent --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000205f00 {"d":{"$numberDecimal":"0E+6000"}} 180000001364000000000000000000000000000000205f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-029.phpt0000664000175000017500000000150713210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - 0 with Negative Exponent --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000007a2b00 {"d":{"$numberDecimal":"0E-611"}} 1800000013640000000000000000000000000000007a2b00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-030.phpt0000664000175000017500000000151213210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - No Decimal with Signed Exponent --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000463000 {"d":{"$numberDecimal":"1E+3"}} 180000001364000100000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-031.phpt0000664000175000017500000000150013210321137022667 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Trailing Zero --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001a04000000000000000000000000423000 {"d":{"$numberDecimal":"1.050E+4"}} 180000001364001a04000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-032.phpt0000664000175000017500000000147513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - With Decimal --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006900000000000000000000000000423000 {"d":{"$numberDecimal":"1.05E+3"}} 180000001364006900000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-033.phpt0000664000175000017500000000155313210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Full --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffffffffffffffffffffffff403000 {"d":{"$numberDecimal":"5192296858534827628530496329220095"}} 18000000136400ffffffffffffffffffffffffffff403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-034.phpt0000664000175000017500000000157213210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Large --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000000000E+6144"}} 18000000136400000000000a5bc138938d44c64d31fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-035.phpt0000664000175000017500000000157413210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: Scientific - Largest --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff638e8d37c087adbe09edff5f00 {"d":{"$numberDecimal":"9.999999999999999999999999999999999E+6144"}} 18000000136400ffffffff638e8d37c087adbe09edff5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-036.phpt0000664000175000017500000000204113210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - Exponent Normalization --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640064000000000000000000000000002cb000 {"d":{"$numberDecimal":"-1.00E-8"}} 1800000013640064000000000000000000000000002cb000 1800000013640064000000000000000000000000002cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-037.phpt0000664000175000017500000000203013210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - Unsigned Positive Exponent --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000463000 {"d":{"$numberDecimal":"1E+3"}} 180000001364000100000000000000000000000000463000 180000001364000100000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-038.phpt0000664000175000017500000000203413210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - Lowercase Exponent Identifier --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000463000 {"d":{"$numberDecimal":"1E+3"}} 180000001364000100000000000000000000000000463000 180000001364000100000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-039.phpt0000664000175000017500000000214413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - Long Significand with Exponent --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640079d9e0f9763ada429d0200000000583000 {"d":{"$numberDecimal":"1.2345689012345789012345E+34"}} 1800000013640079d9e0f9763ada429d0200000000583000 1800000013640079d9e0f9763ada429d0200000000583000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-040.phpt0000664000175000017500000000214713210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - Positive Sign --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3c403000 {"d":{"$numberDecimal":"1234567890123456789012345678901234"}} 18000000136400f2af967ed05c82de3297ff6fde3c403000 18000000136400f2af967ed05c82de3297ff6fde3c403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-041.phpt0000664000175000017500000000377213210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - Long Decimal String --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000722800 {"d":{"$numberDecimal":"1E-999"}} 180000001364000100000000000000000000000000722800 180000001364000100000000000000000000000000722800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-042.phpt0000664000175000017500000000177713210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - nan --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007c00 {"d":{"$numberDecimal":"NaN"}} 180000001364000000000000000000000000000000007c00 180000001364000000000000000000000000000000007c00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-043.phpt0000664000175000017500000000177713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - nAn --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007c00 {"d":{"$numberDecimal":"NaN"}} 180000001364000000000000000000000000000000007c00 180000001364000000000000000000000000000000007c00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-044.phpt0000664000175000017500000000202513210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - +infinity --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007800 {"d":{"$numberDecimal":"Infinity"}} 180000001364000000000000000000000000000000007800 180000001364000000000000000000000000000000007800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-045.phpt0000664000175000017500000000202313210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - infinity --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007800 {"d":{"$numberDecimal":"Infinity"}} 180000001364000000000000000000000000000000007800 180000001364000000000000000000000000000000007800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-046.phpt0000664000175000017500000000202313210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - infiniTY --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007800 {"d":{"$numberDecimal":"Infinity"}} 180000001364000000000000000000000000000000007800 180000001364000000000000000000000000000000007800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-047.phpt0000664000175000017500000000201113210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - inf --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007800 {"d":{"$numberDecimal":"Infinity"}} 180000001364000000000000000000000000000000007800 180000001364000000000000000000000000000000007800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-048.phpt0000664000175000017500000000201113210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - inF --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007800 {"d":{"$numberDecimal":"Infinity"}} 180000001364000000000000000000000000000000007800 180000001364000000000000000000000000000000007800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-049.phpt0000664000175000017500000000202713210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - -infinity --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000f800 {"d":{"$numberDecimal":"-Infinity"}} 18000000136400000000000000000000000000000000f800 18000000136400000000000000000000000000000000f800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-050.phpt0000664000175000017500000000202713210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - -infiniTy --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000f800 {"d":{"$numberDecimal":"-Infinity"}} 18000000136400000000000000000000000000000000f800 18000000136400000000000000000000000000000000f800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-051.phpt0000664000175000017500000000202213210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - -Inf --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000f800 {"d":{"$numberDecimal":"-Infinity"}} 18000000136400000000000000000000000000000000f800 18000000136400000000000000000000000000000000f800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-052.phpt0000664000175000017500000000201513210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - -inf --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000f800 {"d":{"$numberDecimal":"-Infinity"}} 18000000136400000000000000000000000000000000f800 18000000136400000000000000000000000000000000f800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-053.phpt0000664000175000017500000000201513210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: Non-Canonical Parsing - -inF --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000f800 {"d":{"$numberDecimal":"-Infinity"}} 18000000136400000000000000000000000000000000f800 18000000136400000000000000000000000000000000f800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-054.phpt0000664000175000017500000000201113210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: Rounded Subnormal number --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000000000 {"d":{"$numberDecimal":"1E-6176"}} 180000001364000100000000000000000000000000000000 180000001364000100000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-055.phpt0000664000175000017500000000177213210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: Clamped --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0E+6112"}} 180000001364000a00000000000000000000000000fe5f00 180000001364000a00000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-1-valid-056.phpt0000664000175000017500000000404113210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: Exact rounding --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31cc3700 {"d":{"$numberDecimal":"1.000000000000000000000000000000000E+999"}} 18000000136400000000000a5bc138938d44c64d31cc3700 18000000136400000000000a5bc138938d44c64d31cc3700 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-001.phpt0000664000175000017500000000155713210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq021] Normality --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3c40b000 {"d":{"$numberDecimal":"-1234567890123456789012345678901234"}} 18000000136400f2af967ed05c82de3297ff6fde3c40b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-002.phpt0000664000175000017500000000154713210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq823] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400010000800000000000000000000040b000 {"d":{"$numberDecimal":"-2147483649"}} 18000000136400010000800000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-003.phpt0000664000175000017500000000154713210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq822] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000800000000000000000000040b000 {"d":{"$numberDecimal":"-2147483648"}} 18000000136400000000800000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-004.phpt0000664000175000017500000000154713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq821] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffff7f0000000000000000000040b000 {"d":{"$numberDecimal":"-2147483647"}} 18000000136400ffffff7f0000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-005.phpt0000664000175000017500000000154713210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq820] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400feffff7f0000000000000000000040b000 {"d":{"$numberDecimal":"-2147483646"}} 18000000136400feffff7f0000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-006.phpt0000664000175000017500000000150313210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq152] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400393000000000000000000000000040b000 {"d":{"$numberDecimal":"-12345"}} 18000000136400393000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-007.phpt0000664000175000017500000000150113210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [decq154] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400d20400000000000000000000000040b000 {"d":{"$numberDecimal":"-1234"}} 18000000136400d20400000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-008.phpt0000664000175000017500000000151213210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq006] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee0200000000000000000000000040b000 {"d":{"$numberDecimal":"-750"}} 18000000136400ee0200000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-009.phpt0000664000175000017500000000150513210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq164] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640039300000000000000000000000003cb000 {"d":{"$numberDecimal":"-123.45"}} 1800000013640039300000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-010.phpt0000664000175000017500000000147713210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq156] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364007b0000000000000000000000000040b000 {"d":{"$numberDecimal":"-123"}} 180000001364007b0000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-011.phpt0000664000175000017500000000151413210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [decq008] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee020000000000000000000000003eb000 {"d":{"$numberDecimal":"-75.0"}} 18000000136400ee020000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-012.phpt0000664000175000017500000000147513210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq158] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000c0000000000000000000000000040b000 {"d":{"$numberDecimal":"-12"}} 180000001364000c0000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-013.phpt0000664000175000017500000000160413210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq122] Nmax and similar --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff638e8d37c087adbe09edffdf00 {"d":{"$numberDecimal":"-9.999999999999999999999999999999999E+6144"}} 18000000136400ffffffff638e8d37c087adbe09edffdf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-014.phpt0000664000175000017500000000154413210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq002] (mostly derived from the Strawman 4 document and examples) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee020000000000000000000000003cb000 {"d":{"$numberDecimal":"-7.50"}} 18000000136400ee020000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-015.phpt0000664000175000017500000000152213210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq004] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee0200000000000000000000000042b000 {"d":{"$numberDecimal":"-7.50E+3"}} 18000000136400ee0200000000000000000000000042b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-016.phpt0000664000175000017500000000152213210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq018] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee020000000000000000000000002eb000 {"d":{"$numberDecimal":"-7.50E-7"}} 18000000136400ee020000000000000000000000002eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-017.phpt0000664000175000017500000000160413210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq125] Nmax and similar --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3cfedf00 {"d":{"$numberDecimal":"-1.234567890123456789012345678901234E+6144"}} 18000000136400f2af967ed05c82de3297ff6fde3cfedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-018.phpt0000664000175000017500000000161313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq131] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000807f1bcf85b27059c8a43cfedf00 {"d":{"$numberDecimal":"-1.230000000000000000000000000000000E+6144"}} 18000000136400000000807f1bcf85b27059c8a43cfedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-019.phpt0000664000175000017500000000150113210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq162] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364007b000000000000000000000000003cb000 {"d":{"$numberDecimal":"-1.23"}} 180000001364007b000000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-020.phpt0000664000175000017500000000160213210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [decq176] Nmin and below --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400010000000a5bc138938d44c64d31008000 {"d":{"$numberDecimal":"-1.000000000000000000000000000000001E-6143"}} 18000000136400010000000a5bc138938d44c64d31008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-021.phpt0000664000175000017500000000160213210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: [decq174] Nmin and below --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31008000 {"d":{"$numberDecimal":"-1.000000000000000000000000000000000E-6143"}} 18000000136400000000000a5bc138938d44c64d31008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-022.phpt0000664000175000017500000000161313210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq133] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31fedf00 {"d":{"$numberDecimal":"-1.000000000000000000000000000000000E+6144"}} 18000000136400000000000a5bc138938d44c64d31fedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-023.phpt0000664000175000017500000000147313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq160] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400010000000000000000000000000040b000 {"d":{"$numberDecimal":"-1"}} 18000000136400010000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-024.phpt0000664000175000017500000000147613210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq172] Nmin and below --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000428000 {"d":{"$numberDecimal":"-1E-6143"}} 180000001364000100000000000000000000000000428000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-025.phpt0000664000175000017500000000151613210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq010] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee020000000000000000000000003ab000 {"d":{"$numberDecimal":"-0.750"}} 18000000136400ee020000000000000000000000003ab000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-026.phpt0000664000175000017500000000152013210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq012] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee0200000000000000000000000038b000 {"d":{"$numberDecimal":"-0.0750"}} 18000000136400ee0200000000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-027.phpt0000664000175000017500000000152413210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq014] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee0200000000000000000000000034b000 {"d":{"$numberDecimal":"-0.000750"}} 18000000136400ee0200000000000000000000000034b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-028.phpt0000664000175000017500000000153013210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq016] derivative canonical plain strings --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ee0200000000000000000000000030b000 {"d":{"$numberDecimal":"-0.00000750"}} 18000000136400ee0200000000000000000000000030b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-029.phpt0000664000175000017500000000146313210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq404] zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000000000 {"d":{"$numberDecimal":"0E-6176"}} 180000001364000000000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-030.phpt0000664000175000017500000000147613210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq424] negative zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000008000 {"d":{"$numberDecimal":"-0E-6176"}} 180000001364000000000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-031.phpt0000664000175000017500000000145513210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq407] zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.00"}} 1800000013640000000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-032.phpt0000664000175000017500000000147013210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq427] negative zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003cb000 {"d":{"$numberDecimal":"-0.00"}} 1800000013640000000000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-033.phpt0000664000175000017500000000144713210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq409] zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-034.phpt0000664000175000017500000000146213210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq428] negative zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000040b000 {"d":{"$numberDecimal":"-0"}} 18000000136400000000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-035.phpt0000664000175000017500000000146413210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq700] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-036.phpt0000664000175000017500000000145513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq406] zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.00"}} 1800000013640000000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-037.phpt0000664000175000017500000000147013210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq426] negative zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003cb000 {"d":{"$numberDecimal":"-0.00"}} 1800000013640000000000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-038.phpt0000664000175000017500000000145513210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq410] zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000463000 {"d":{"$numberDecimal":"0E+3"}} 180000001364000000000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-039.phpt0000664000175000017500000000147013210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq431] negative zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000046b000 {"d":{"$numberDecimal":"-0E+3"}} 18000000136400000000000000000000000000000046b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-040.phpt0000664000175000017500000000147613210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq419] clamped zeros... --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fe5f00 {"d":{"$numberDecimal":"0E+6111"}} 180000001364000000000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-041.phpt0000664000175000017500000000147613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq432] negative zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fedf00 {"d":{"$numberDecimal":"-0E+6111"}} 180000001364000000000000000000000000000000fedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-042.phpt0000664000175000017500000000146313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq405] zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000000000 {"d":{"$numberDecimal":"0E-6176"}} 180000001364000000000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-043.phpt0000664000175000017500000000147613210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq425] negative zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000008000 {"d":{"$numberDecimal":"-0E-6176"}} 180000001364000000000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-044.phpt0000664000175000017500000000147013210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq508] Specials --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007800 {"d":{"$numberDecimal":"Infinity"}} 180000001364000000000000000000000000000000007800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-045.phpt0000664000175000017500000000147213210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq528] Specials --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000000f800 {"d":{"$numberDecimal":"-Infinity"}} 18000000136400000000000000000000000000000000f800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-046.phpt0000664000175000017500000000145613210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq541] Specials --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000007c00 {"d":{"$numberDecimal":"NaN"}} 180000001364000000000000000000000000000000007c00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-047.phpt0000664000175000017500000000160013210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq074] Nmin and below --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31000000 {"d":{"$numberDecimal":"1.000000000000000000000000000000000E-6143"}} 18000000136400000000000a5bc138938d44c64d31000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-048.phpt0000664000175000017500000000161113210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq602] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000000000E+6144"}} 18000000136400000000000a5bc138938d44c64d31fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-049.phpt0000664000175000017500000000160713210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq604] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000081efac855b416d2dee04fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000000000000E+6143"}} 180000001364000000000081efac855b416d2dee04fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-050.phpt0000664000175000017500000000160513210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq606] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000080264b91c02220be377e00fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000000000000E+6142"}} 1800000013640000000080264b91c02220be377e00fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-051.phpt0000664000175000017500000000160313210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq608] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000040eaed7446d09c2c9f0c00fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000000E+6141"}} 1800000013640000000040eaed7446d09c2c9f0c00fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-052.phpt0000664000175000017500000000160113210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq610] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000a0ca17726dae0f1e430100fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000000000E+6140"}} 18000000136400000000a0ca17726dae0f1e430100fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-053.phpt0000664000175000017500000000157713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq612] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000106102253e5ece4f200000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000000000E+6139"}} 18000000136400000000106102253e5ece4f200000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-054.phpt0000664000175000017500000000157513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq614] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000e83c80d09f3c2e3b030000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000E+6138"}} 18000000136400000000e83c80d09f3c2e3b030000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-055.phpt0000664000175000017500000000157313210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq616] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000e4d20cc8dcd2b752000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000000E+6137"}} 18000000136400000000e4d20cc8dcd2b752000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-056.phpt0000664000175000017500000000157113210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq618] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000004a48011416954508000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000000E+6136"}} 180000001364000000004a48011416954508000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-057.phpt0000664000175000017500000000156713210321137022715 0ustar jmikolajmikola--TEST-- Decimal128: [decq620] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000a1edccce1bc2d300000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000E+6135"}} 18000000136400000000a1edccce1bc2d300000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-058.phpt0000664000175000017500000000156513210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [decq622] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000080f64ae1c7022d1500000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000E+6134"}} 18000000136400000080f64ae1c7022d1500000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-059.phpt0000664000175000017500000000156313210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [decq624] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000040b2bac9e0191e0200000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000E+6133"}} 18000000136400000040b2bac9e0191e0200000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-060.phpt0000664000175000017500000000156113210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq626] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000a0dec5adc935360000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000E+6132"}} 180000001364000000a0dec5adc935360000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-061.phpt0000664000175000017500000000155713210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq628] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000010632d5ec76b050000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000E+6131"}} 18000000136400000010632d5ec76b050000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-062.phpt0000664000175000017500000000155513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq630] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000e8890423c78a000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000E+6130"}} 180000001364000000e8890423c78a000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-063.phpt0000664000175000017500000000155313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq632] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000064a7b3b6e00d000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000E+6129"}} 18000000136400000064a7b3b6e00d000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-064.phpt0000664000175000017500000000155113210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq634] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000008a5d78456301000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000E+6128"}} 1800000013640000008a5d78456301000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-065.phpt0000664000175000017500000000154713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq636] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000c16ff2862300000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000E+6127"}} 180000001364000000c16ff2862300000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-066.phpt0000664000175000017500000000154513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq638] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000080c6a47e8d0300000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000E+6126"}} 180000001364000080c6a47e8d0300000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-067.phpt0000664000175000017500000000154313210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq640] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000407a10f35a0000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000E+6125"}} 1800000013640000407a10f35a0000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-068.phpt0000664000175000017500000000154113210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq642] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000a0724e18090000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000E+6124"}} 1800000013640000a0724e18090000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-069.phpt0000664000175000017500000000153713210321137022715 0ustar jmikolajmikola--TEST-- Decimal128: [decq644] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000010a5d4e8000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000E+6123"}} 180000001364000010a5d4e8000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-070.phpt0000664000175000017500000000153513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq646] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000e8764817000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000E+6122"}} 1800000013640000e8764817000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-071.phpt0000664000175000017500000000153313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq648] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000e40b5402000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000E+6121"}} 1800000013640000e40b5402000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-072.phpt0000664000175000017500000000153113210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq650] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000ca9a3b00000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000E+6120"}} 1800000013640000ca9a3b00000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-073.phpt0000664000175000017500000000152713210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq652] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000e1f50500000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000E+6119"}} 1800000013640000e1f50500000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-074.phpt0000664000175000017500000000152513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq654] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364008096980000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000E+6118"}} 180000001364008096980000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-075.phpt0000664000175000017500000000152313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq656] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640040420f0000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000000E+6117"}} 1800000013640040420f0000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-076.phpt0000664000175000017500000000152113210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq658] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400a086010000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000E+6116"}} 18000000136400a086010000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-077.phpt0000664000175000017500000000151713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq660] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001027000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000E+6115"}} 180000001364001027000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-078.phpt0000664000175000017500000000151513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq662] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e803000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000E+6114"}} 18000000136400e803000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-079.phpt0000664000175000017500000000151313210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq664] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006400000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00E+6113"}} 180000001364006400000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-080.phpt0000664000175000017500000000151113210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq666] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0E+6112"}} 180000001364000a00000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-081.phpt0000664000175000017500000000147113210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq060] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000403000 {"d":{"$numberDecimal":"1"}} 180000001364000100000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-082.phpt0000664000175000017500000000150513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq670] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000fc5f00 {"d":{"$numberDecimal":"1E+6110"}} 180000001364000100000000000000000000000000fc5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-083.phpt0000664000175000017500000000150513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq668] fold-down full sequence --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1E+6111"}} 180000001364000100000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-084.phpt0000664000175000017500000000147413210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq072] Nmin and below --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000420000 {"d":{"$numberDecimal":"1E-6143"}} 180000001364000100000000000000000000000000420000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-085.phpt0000664000175000017500000000160013210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq076] Nmin and below --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400010000000a5bc138938d44c64d31000000 {"d":{"$numberDecimal":"1.000000000000000000000000000000001E-6143"}} 18000000136400010000000a5bc138938d44c64d31000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-086.phpt0000664000175000017500000000161113210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq036] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000807f1bcf85b27059c8a43cfe5f00 {"d":{"$numberDecimal":"1.230000000000000000000000000000000E+6144"}} 18000000136400000000807f1bcf85b27059c8a43cfe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-087.phpt0000664000175000017500000000147713210321137022720 0ustar jmikolajmikola--TEST-- Decimal128: [decq062] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364007b000000000000000000000000003c3000 {"d":{"$numberDecimal":"1.23"}} 180000001364007b000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-088.phpt0000664000175000017500000000160213210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq034] Nmax and similar --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3cfe5f00 {"d":{"$numberDecimal":"1.234567890123456789012345678901234E+6144"}} 18000000136400f2af967ed05c82de3297ff6fde3cfe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-089.phpt0000664000175000017500000000146213210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [decq441] exponent lengths --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000403000 {"d":{"$numberDecimal":"7"}} 180000001364000700000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-090.phpt0000664000175000017500000000147613210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq449] exponent lengths --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000001e5f00 {"d":{"$numberDecimal":"7E+5999"}} 1800000013640007000000000000000000000000001e5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-091.phpt0000664000175000017500000000147413210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq447] exponent lengths --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000000e3800 {"d":{"$numberDecimal":"7E+999"}} 1800000013640007000000000000000000000000000e3800 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-092.phpt0000664000175000017500000000147213210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq445] exponent lengths --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000063100 {"d":{"$numberDecimal":"7E+99"}} 180000001364000700000000000000000000000000063100 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-093.phpt0000664000175000017500000000147013210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq443] exponent lengths --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000523000 {"d":{"$numberDecimal":"7E+9"}} 180000001364000700000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-094.phpt0000664000175000017500000000157513210321137022715 0ustar jmikolajmikola--TEST-- Decimal128: [decq842] VG testcase --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000fed83f4e7c9fe4e269e38a5bcd1700 {"d":{"$numberDecimal":"7.049000000000010795488000000000000E-3097"}} 180000001364000000fed83f4e7c9fe4e269e38a5bcd1700 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-095.phpt0000664000175000017500000000153713210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [decq841] VG testcase --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000203b9db5056f000000000000002400 {"d":{"$numberDecimal":"8.000000000000000000E-1550"}} 180000001364000000203b9db5056f000000000000002400 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-096.phpt0000664000175000017500000000154313210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq840] VG testcase --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003c17258419d710c42f0000000000002400 {"d":{"$numberDecimal":"8.81125000000001349436E-1548"}} 180000001364003c17258419d710c42f0000000000002400 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-097.phpt0000664000175000017500000000146413210321137022715 0ustar jmikolajmikola--TEST-- Decimal128: [decq701] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000900000000000000000000000000403000 {"d":{"$numberDecimal":"9"}} 180000001364000900000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-098.phpt0000664000175000017500000000160213210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq032] Nmax and similar --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff638e8d37c087adbe09edff5f00 {"d":{"$numberDecimal":"9.999999999999999999999999999999999E+6144"}} 18000000136400ffffffff638e8d37c087adbe09edff5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-099.phpt0000664000175000017500000000146613210321137022721 0ustar jmikolajmikola--TEST-- Decimal128: [decq702] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000403000 {"d":{"$numberDecimal":"10"}} 180000001364000a00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-100.phpt0000664000175000017500000000147313210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq057] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000c00000000000000000000000000403000 {"d":{"$numberDecimal":"12"}} 180000001364000c00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-101.phpt0000664000175000017500000000146613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq703] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001300000000000000000000000000403000 {"d":{"$numberDecimal":"19"}} 180000001364001300000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-102.phpt0000664000175000017500000000146613210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq704] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001400000000000000000000000000403000 {"d":{"$numberDecimal":"20"}} 180000001364001400000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-103.phpt0000664000175000017500000000146613210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq705] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001d00000000000000000000000000403000 {"d":{"$numberDecimal":"29"}} 180000001364001d00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-104.phpt0000664000175000017500000000146613210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq706] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001e00000000000000000000000000403000 {"d":{"$numberDecimal":"30"}} 180000001364001e00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-105.phpt0000664000175000017500000000146613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq707] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364002700000000000000000000000000403000 {"d":{"$numberDecimal":"39"}} 180000001364002700000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-106.phpt0000664000175000017500000000146613210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq708] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364002800000000000000000000000000403000 {"d":{"$numberDecimal":"40"}} 180000001364002800000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-107.phpt0000664000175000017500000000146613210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq709] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003100000000000000000000000000403000 {"d":{"$numberDecimal":"49"}} 180000001364003100000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-108.phpt0000664000175000017500000000146613210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq710] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003200000000000000000000000000403000 {"d":{"$numberDecimal":"50"}} 180000001364003200000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-109.phpt0000664000175000017500000000146613210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq711] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003b00000000000000000000000000403000 {"d":{"$numberDecimal":"59"}} 180000001364003b00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-110.phpt0000664000175000017500000000146613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq712] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003c00000000000000000000000000403000 {"d":{"$numberDecimal":"60"}} 180000001364003c00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-111.phpt0000664000175000017500000000146613210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq713] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004500000000000000000000000000403000 {"d":{"$numberDecimal":"69"}} 180000001364004500000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-112.phpt0000664000175000017500000000146613210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq714] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004600000000000000000000000000403000 {"d":{"$numberDecimal":"70"}} 180000001364004600000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-113.phpt0000664000175000017500000000146613210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq715] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004700000000000000000000000000403000 {"d":{"$numberDecimal":"71"}} 180000001364004700000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-114.phpt0000664000175000017500000000146613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq716] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004800000000000000000000000000403000 {"d":{"$numberDecimal":"72"}} 180000001364004800000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-115.phpt0000664000175000017500000000146613210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq717] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004900000000000000000000000000403000 {"d":{"$numberDecimal":"73"}} 180000001364004900000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-116.phpt0000664000175000017500000000146613210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq718] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004a00000000000000000000000000403000 {"d":{"$numberDecimal":"74"}} 180000001364004a00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-117.phpt0000664000175000017500000000146613210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq719] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004b00000000000000000000000000403000 {"d":{"$numberDecimal":"75"}} 180000001364004b00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-118.phpt0000664000175000017500000000146613210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq720] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004c00000000000000000000000000403000 {"d":{"$numberDecimal":"76"}} 180000001364004c00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-119.phpt0000664000175000017500000000146613210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq721] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004d00000000000000000000000000403000 {"d":{"$numberDecimal":"77"}} 180000001364004d00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-120.phpt0000664000175000017500000000146613210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq722] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004e00000000000000000000000000403000 {"d":{"$numberDecimal":"78"}} 180000001364004e00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-121.phpt0000664000175000017500000000146613210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq723] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004f00000000000000000000000000403000 {"d":{"$numberDecimal":"79"}} 180000001364004f00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-122.phpt0000664000175000017500000000147513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq056] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364007b00000000000000000000000000403000 {"d":{"$numberDecimal":"123"}} 180000001364007b00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-123.phpt0000664000175000017500000000150313210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq064] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640039300000000000000000000000003c3000 {"d":{"$numberDecimal":"123.45"}} 1800000013640039300000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-124.phpt0000664000175000017500000000147013210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq732] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000802000000000000000000000000403000 {"d":{"$numberDecimal":"520"}} 180000001364000802000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-125.phpt0000664000175000017500000000147013210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq733] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000902000000000000000000000000403000 {"d":{"$numberDecimal":"521"}} 180000001364000902000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-126.phpt0000664000175000017500000000151413210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq740] DPD: one of each of the huffman groups --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000903000000000000000000000000403000 {"d":{"$numberDecimal":"777"}} 180000001364000903000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-127.phpt0000664000175000017500000000151413210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq741] DPD: one of each of the huffman groups --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a03000000000000000000000000403000 {"d":{"$numberDecimal":"778"}} 180000001364000a03000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-128.phpt0000664000175000017500000000151413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq742] DPD: one of each of the huffman groups --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001303000000000000000000000000403000 {"d":{"$numberDecimal":"787"}} 180000001364001303000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-129.phpt0000664000175000017500000000151413210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq746] DPD: one of each of the huffman groups --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001f03000000000000000000000000403000 {"d":{"$numberDecimal":"799"}} 180000001364001f03000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-130.phpt0000664000175000017500000000151413210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq743] DPD: one of each of the huffman groups --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006d03000000000000000000000000403000 {"d":{"$numberDecimal":"877"}} 180000001364006d03000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-131.phpt0000664000175000017500000000153313210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq753] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364007803000000000000000000000000403000 {"d":{"$numberDecimal":"888"}} 180000001364007803000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-132.phpt0000664000175000017500000000153313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq754] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364007903000000000000000000000000403000 {"d":{"$numberDecimal":"889"}} 180000001364007903000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-133.phpt0000664000175000017500000000153313210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq760] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364008203000000000000000000000000403000 {"d":{"$numberDecimal":"898"}} 180000001364008203000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-134.phpt0000664000175000017500000000153313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq764] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364008303000000000000000000000000403000 {"d":{"$numberDecimal":"899"}} 180000001364008303000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-135.phpt0000664000175000017500000000151413210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq745] DPD: one of each of the huffman groups --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400d303000000000000000000000000403000 {"d":{"$numberDecimal":"979"}} 18000000136400d303000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-136.phpt0000664000175000017500000000153313210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq770] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400dc03000000000000000000000000403000 {"d":{"$numberDecimal":"988"}} 18000000136400dc03000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-137.phpt0000664000175000017500000000153313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq774] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400dd03000000000000000000000000403000 {"d":{"$numberDecimal":"989"}} 18000000136400dd03000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-138.phpt0000664000175000017500000000147013210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq730] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e203000000000000000000000000403000 {"d":{"$numberDecimal":"994"}} 18000000136400e203000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-139.phpt0000664000175000017500000000147013210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq731] Selected DPD codes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e303000000000000000000000000403000 {"d":{"$numberDecimal":"995"}} 18000000136400e303000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-140.phpt0000664000175000017500000000151413210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq744] DPD: one of each of the huffman groups --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e503000000000000000000000000403000 {"d":{"$numberDecimal":"997"}} 18000000136400e503000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-141.phpt0000664000175000017500000000153313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq780] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e603000000000000000000000000403000 {"d":{"$numberDecimal":"998"}} 18000000136400e603000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-142.phpt0000664000175000017500000000153313210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq787] DPD all-highs cases (includes the 24 redundant codes) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e703000000000000000000000000403000 {"d":{"$numberDecimal":"999"}} 18000000136400e703000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-143.phpt0000664000175000017500000000147713210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq053] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400d204000000000000000000000000403000 {"d":{"$numberDecimal":"1234"}} 18000000136400d204000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-144.phpt0000664000175000017500000000150113210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq052] fold-downs (more below) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003930000000000000000000000000403000 {"d":{"$numberDecimal":"12345"}} 180000001364003930000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-145.phpt0000664000175000017500000000152013210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq792] Miscellaneous (testers' queries, etc.) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003075000000000000000000000000403000 {"d":{"$numberDecimal":"30000"}} 180000001364003075000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-146.phpt0000664000175000017500000000152213210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq793] Miscellaneous (testers' queries, etc.) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640090940d0000000000000000000000403000 {"d":{"$numberDecimal":"890000"}} 1800000013640090940d0000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-147.phpt0000664000175000017500000000154513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq824] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400feffff7f00000000000000000000403000 {"d":{"$numberDecimal":"2147483646"}} 18000000136400feffff7f00000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-148.phpt0000664000175000017500000000154513210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq825] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffff7f00000000000000000000403000 {"d":{"$numberDecimal":"2147483647"}} 18000000136400ffffff7f00000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-149.phpt0000664000175000017500000000154513210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [decq826] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000008000000000000000000000403000 {"d":{"$numberDecimal":"2147483648"}} 180000001364000000008000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-150.phpt0000664000175000017500000000154513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq827] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100008000000000000000000000403000 {"d":{"$numberDecimal":"2147483649"}} 180000001364000100008000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-151.phpt0000664000175000017500000000154513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq828] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400feffffff00000000000000000000403000 {"d":{"$numberDecimal":"4294967294"}} 18000000136400feffffff00000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-152.phpt0000664000175000017500000000154513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq829] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff00000000000000000000403000 {"d":{"$numberDecimal":"4294967295"}} 18000000136400ffffffff00000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-153.phpt0000664000175000017500000000154513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq830] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000001000000000000000000403000 {"d":{"$numberDecimal":"4294967296"}} 180000001364000000000001000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-154.phpt0000664000175000017500000000154513210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq831] values around [u]int32 edges (zeros done earlier) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000001000000000000000000403000 {"d":{"$numberDecimal":"4294967297"}} 180000001364000100000001000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-155.phpt0000664000175000017500000000155513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq022] Normality --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400c7711cc7b548f377dc80a131c836403000 {"d":{"$numberDecimal":"1111111111111111111111111111111111"}} 18000000136400c7711cc7b548f377dc80a131c836403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-156.phpt0000664000175000017500000000155513210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq020] Normality --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f2af967ed05c82de3297ff6fde3c403000 {"d":{"$numberDecimal":"1234567890123456789012345678901234"}} 18000000136400f2af967ed05c82de3297ff6fde3c403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-2-valid-157.phpt0000664000175000017500000000155413210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq550] Specials --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff638e8d37c087adbe09ed413000 {"d":{"$numberDecimal":"9999999999999999999999999999999999"}} 18000000136400ffffffff638e8d37c087adbe09ed413000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-001.phpt0000664000175000017500000000207013210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [basx066] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400185c0ace0000000000000000000038b000 {"d":{"$numberDecimal":"-345678.5432"}} 18000000136400185c0ace0000000000000000000038b000 18000000136400185c0ace0000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-002.phpt0000664000175000017500000000206713210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx065] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400185c0ace0000000000000000000038b000 {"d":{"$numberDecimal":"-345678.5432"}} 18000000136400185c0ace0000000000000000000038b000 18000000136400185c0ace0000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-003.phpt0000664000175000017500000000154513210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx064] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400185c0ace0000000000000000000038b000 {"d":{"$numberDecimal":"-345678.5432"}} 18000000136400185c0ace0000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-004.phpt0000664000175000017500000000152313210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx041] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364004c0000000000000000000000000040b000 {"d":{"$numberDecimal":"-76"}} 180000001364004c0000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-005.phpt0000664000175000017500000000154613210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx027] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000f270000000000000000000000003ab000 {"d":{"$numberDecimal":"-9.999"}} 180000001364000f270000000000000000000000003ab000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-006.phpt0000664000175000017500000000154613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx026] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364009f230000000000000000000000003ab000 {"d":{"$numberDecimal":"-9.119"}} 180000001364009f230000000000000000000000003ab000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-007.phpt0000664000175000017500000000154413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx025] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364008f030000000000000000000000003cb000 {"d":{"$numberDecimal":"-9.11"}} 180000001364008f030000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-008.phpt0000664000175000017500000000154213210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx024] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364005b000000000000000000000000003eb000 {"d":{"$numberDecimal":"-9.1"}} 180000001364005b000000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-009.phpt0000664000175000017500000000214613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr531] negatives (Rounded) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640099761cc7b548f377dc80a131c836feaf00 {"d":{"$numberDecimal":"-1.111111111111111111111111111112345"}} 1800000013640099761cc7b548f377dc80a131c836feaf00 1800000013640099761cc7b548f377dc80a131c836feaf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-010.phpt0000664000175000017500000000154213210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx022] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000003eb000 {"d":{"$numberDecimal":"-1.0"}} 180000001364000a000000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-011.phpt0000664000175000017500000000153613210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx021] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400010000000000000000000000000040b000 {"d":{"$numberDecimal":"-1"}} 18000000136400010000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-012.phpt0000664000175000017500000000177513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx601] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002e3000 {"d":{"$numberDecimal":"0E-9"}} 1800000013640000000000000000000000000000002e3000 1800000013640000000000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-013.phpt0000664000175000017500000000200013210321137022665 0ustar jmikolajmikola--TEST-- Decimal128: [basx622] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002eb000 {"d":{"$numberDecimal":"-0E-9"}} 1800000013640000000000000000000000000000002eb000 1800000013640000000000000000000000000000002eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-014.phpt0000664000175000017500000000177413210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx602] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000303000 {"d":{"$numberDecimal":"0E-8"}} 180000001364000000000000000000000000000000303000 180000001364000000000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-015.phpt0000664000175000017500000000177713210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx621] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000030b000 {"d":{"$numberDecimal":"-0E-8"}} 18000000136400000000000000000000000000000030b000 18000000136400000000000000000000000000000030b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-016.phpt0000664000175000017500000000177313210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx603] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000323000 {"d":{"$numberDecimal":"0E-7"}} 180000001364000000000000000000000000000000323000 180000001364000000000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-017.phpt0000664000175000017500000000177613210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [basx620] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000032b000 {"d":{"$numberDecimal":"-0E-7"}} 18000000136400000000000000000000000000000032b000 18000000136400000000000000000000000000000032b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-018.phpt0000664000175000017500000000146513210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx604] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000343000 {"d":{"$numberDecimal":"0.000000"}} 180000001364000000000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-019.phpt0000664000175000017500000000146713210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx619] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000034b000 {"d":{"$numberDecimal":"-0.000000"}} 18000000136400000000000000000000000000000034b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-020.phpt0000664000175000017500000000146313210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx605] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000363000 {"d":{"$numberDecimal":"0.00000"}} 180000001364000000000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-021.phpt0000664000175000017500000000146513210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx618] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000036b000 {"d":{"$numberDecimal":"-0.00000"}} 18000000136400000000000000000000000000000036b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-022.phpt0000664000175000017500000000176313210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx680] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-023.phpt0000664000175000017500000000146113210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx606] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000383000 {"d":{"$numberDecimal":"0.0000"}} 180000001364000000000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-024.phpt0000664000175000017500000000146313210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx617] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000038b000 {"d":{"$numberDecimal":"-0.0000"}} 18000000136400000000000000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-025.phpt0000664000175000017500000000176213210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx681] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-026.phpt0000664000175000017500000000176313210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx686] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-027.phpt0000664000175000017500000000176513210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx687] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000040b000 {"d":{"$numberDecimal":"-0"}} 18000000136400000000000000000000000000000040b000 18000000136400000000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-028.phpt0000664000175000017500000000205713210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx019] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003cb000 {"d":{"$numberDecimal":"-0.00"}} 1800000013640000000000000000000000000000003cb000 1800000013640000000000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-029.phpt0000664000175000017500000000145713210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx607] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.000"}} 1800000013640000000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-030.phpt0000664000175000017500000000146113210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx616] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003ab000 {"d":{"$numberDecimal":"-0.000"}} 1800000013640000000000000000000000000000003ab000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-031.phpt0000664000175000017500000000176113210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx682] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-032.phpt0000664000175000017500000000200513210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx155] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.000"}} 1800000013640000000000000000000000000000003a3000 1800000013640000000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-033.phpt0000664000175000017500000000200713210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx130] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000383000 {"d":{"$numberDecimal":"0.0000"}} 180000001364000000000000000000000000000000383000 180000001364000000000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-034.phpt0000664000175000017500000000205513210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx290] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000038b000 {"d":{"$numberDecimal":"-0.0000"}} 18000000136400000000000000000000000000000038b000 18000000136400000000000000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-035.phpt0000664000175000017500000000201113210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx131] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000363000 {"d":{"$numberDecimal":"0.00000"}} 180000001364000000000000000000000000000000363000 180000001364000000000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-036.phpt0000664000175000017500000000205713210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx291] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000036b000 {"d":{"$numberDecimal":"-0.00000"}} 18000000136400000000000000000000000000000036b000 18000000136400000000000000000000000000000036b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-037.phpt0000664000175000017500000000201313210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx132] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000343000 {"d":{"$numberDecimal":"0.000000"}} 180000001364000000000000000000000000000000343000 180000001364000000000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-038.phpt0000664000175000017500000000206113210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx292] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000034b000 {"d":{"$numberDecimal":"-0.000000"}} 18000000136400000000000000000000000000000034b000 18000000136400000000000000000000000000000034b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-039.phpt0000664000175000017500000000200313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx133] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000323000 {"d":{"$numberDecimal":"0E-7"}} 180000001364000000000000000000000000000000323000 180000001364000000000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-040.phpt0000664000175000017500000000205113210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx293] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000032b000 {"d":{"$numberDecimal":"-0E-7"}} 18000000136400000000000000000000000000000032b000 18000000136400000000000000000000000000000032b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-041.phpt0000664000175000017500000000145513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx608] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.00"}} 1800000013640000000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-042.phpt0000664000175000017500000000145713210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx615] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003cb000 {"d":{"$numberDecimal":"-0.00"}} 1800000013640000000000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-043.phpt0000664000175000017500000000176013210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx683] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-044.phpt0000664000175000017500000000177113210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx630] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.00"}} 1800000013640000000000000000000000000000003c3000 1800000013640000000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-045.phpt0000664000175000017500000000177113210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx670] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.00"}} 1800000013640000000000000000000000000000003c3000 1800000013640000000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-046.phpt0000664000175000017500000000176713210321137022716 0ustar jmikolajmikola--TEST-- Decimal128: [basx631] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.0"}} 1800000013640000000000000000000000000000003e3000 1800000013640000000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-047.phpt0000664000175000017500000000177313210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [basx671] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.000"}} 1800000013640000000000000000000000000000003a3000 1800000013640000000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-048.phpt0000664000175000017500000000200613210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx134] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000383000 {"d":{"$numberDecimal":"0.0000"}} 180000001364000000000000000000000000000000383000 180000001364000000000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-049.phpt0000664000175000017500000000205413210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx294] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000038b000 {"d":{"$numberDecimal":"-0.0000"}} 18000000136400000000000000000000000000000038b000 18000000136400000000000000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-050.phpt0000664000175000017500000000176313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx632] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-051.phpt0000664000175000017500000000177513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx672] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000383000 {"d":{"$numberDecimal":"0.0000"}} 180000001364000000000000000000000000000000383000 180000001364000000000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-052.phpt0000664000175000017500000000201013210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [basx135] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000363000 {"d":{"$numberDecimal":"0.00000"}} 180000001364000000000000000000000000000000363000 180000001364000000000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-053.phpt0000664000175000017500000000205613210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx295] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000036b000 {"d":{"$numberDecimal":"-0.00000"}} 18000000136400000000000000000000000000000036b000 18000000136400000000000000000000000000000036b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-054.phpt0000664000175000017500000000177113210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx633] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000423000 {"d":{"$numberDecimal":"0E+1"}} 180000001364000000000000000000000000000000423000 180000001364000000000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-055.phpt0000664000175000017500000000177713210321137022717 0ustar jmikolajmikola--TEST-- Decimal128: [basx673] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000363000 {"d":{"$numberDecimal":"0.00000"}} 180000001364000000000000000000000000000000363000 180000001364000000000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-056.phpt0000664000175000017500000000201213210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx136] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000343000 {"d":{"$numberDecimal":"0.000000"}} 180000001364000000000000000000000000000000343000 180000001364000000000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-057.phpt0000664000175000017500000000200113210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx674] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000343000 {"d":{"$numberDecimal":"0.000000"}} 180000001364000000000000000000000000000000343000 180000001364000000000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-058.phpt0000664000175000017500000000177113210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [basx634] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000443000 {"d":{"$numberDecimal":"0E+2"}} 180000001364000000000000000000000000000000443000 180000001364000000000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-059.phpt0000664000175000017500000000200213210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx137] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000323000 {"d":{"$numberDecimal":"0E-7"}} 180000001364000000000000000000000000000000323000 180000001364000000000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-060.phpt0000664000175000017500000000177113210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx635] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000463000 {"d":{"$numberDecimal":"0E+3"}} 180000001364000000000000000000000000000000463000 180000001364000000000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-061.phpt0000664000175000017500000000177113210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx675] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000323000 {"d":{"$numberDecimal":"0E-7"}} 180000001364000000000000000000000000000000323000 180000001364000000000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-062.phpt0000664000175000017500000000177113210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx636] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000483000 {"d":{"$numberDecimal":"0E+4"}} 180000001364000000000000000000000000000000483000 180000001364000000000000000000000000000000483000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-063.phpt0000664000175000017500000000177113210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx676] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000303000 {"d":{"$numberDecimal":"0E-8"}} 180000001364000000000000000000000000000000303000 180000001364000000000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-064.phpt0000664000175000017500000000177113210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx637] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004a3000 {"d":{"$numberDecimal":"0E+5"}} 1800000013640000000000000000000000000000004a3000 1800000013640000000000000000000000000000004a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-065.phpt0000664000175000017500000000177113210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx677] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002e3000 {"d":{"$numberDecimal":"0E-9"}} 1800000013640000000000000000000000000000002e3000 1800000013640000000000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-066.phpt0000664000175000017500000000177113210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx638] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004c3000 {"d":{"$numberDecimal":"0E+6"}} 1800000013640000000000000000000000000000004c3000 1800000013640000000000000000000000000000004c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-067.phpt0000664000175000017500000000177313210321137022716 0ustar jmikolajmikola--TEST-- Decimal128: [basx678] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002c3000 {"d":{"$numberDecimal":"0E-10"}} 1800000013640000000000000000000000000000002c3000 1800000013640000000000000000000000000000002c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-068.phpt0000664000175000017500000000200113210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx149] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000523000 {"d":{"$numberDecimal":"0E+9"}} 180000001364000000000000000000000000000000523000 180000001364000000000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-069.phpt0000664000175000017500000000177113210321137022716 0ustar jmikolajmikola--TEST-- Decimal128: [basx639] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004e3000 {"d":{"$numberDecimal":"0E+7"}} 1800000013640000000000000000000000000000004e3000 1800000013640000000000000000000000000000004e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-070.phpt0000664000175000017500000000177313210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx679] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002a3000 {"d":{"$numberDecimal":"0E-11"}} 1800000013640000000000000000000000000000002a3000 1800000013640000000000000000000000000000002a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-071.phpt0000664000175000017500000000206613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx063] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400185c0ace00000000000000000000383000 {"d":{"$numberDecimal":"345678.5432"}} 18000000136400185c0ace00000000000000000000383000 18000000136400185c0ace00000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-072.phpt0000664000175000017500000000154213210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx018] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003eb000 {"d":{"$numberDecimal":"-0.0"}} 1800000013640000000000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-073.phpt0000664000175000017500000000145313210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx609] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.0"}} 1800000013640000000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-074.phpt0000664000175000017500000000145513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx614] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003eb000 {"d":{"$numberDecimal":"-0.0"}} 1800000013640000000000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-075.phpt0000664000175000017500000000175713210321137022717 0ustar jmikolajmikola--TEST-- Decimal128: [basx684] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-076.phpt0000664000175000017500000000176613210321137022720 0ustar jmikolajmikola--TEST-- Decimal128: [basx640] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.0"}} 1800000013640000000000000000000000000000003e3000 1800000013640000000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-077.phpt0000664000175000017500000000176613210321137022721 0ustar jmikolajmikola--TEST-- Decimal128: [basx660] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.0"}} 1800000013640000000000000000000000000000003e3000 1800000013640000000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-078.phpt0000664000175000017500000000176213210321137022716 0ustar jmikolajmikola--TEST-- Decimal128: [basx641] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-079.phpt0000664000175000017500000000177013210321137022716 0ustar jmikolajmikola--TEST-- Decimal128: [basx661] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.00"}} 1800000013640000000000000000000000000000003c3000 1800000013640000000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-080.phpt0000664000175000017500000000205113210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx296] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003ab000 {"d":{"$numberDecimal":"-0.000"}} 1800000013640000000000000000000000000000003ab000 1800000013640000000000000000000000000000003ab000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-081.phpt0000664000175000017500000000177013210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx642] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000423000 {"d":{"$numberDecimal":"0E+1"}} 180000001364000000000000000000000000000000423000 180000001364000000000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-082.phpt0000664000175000017500000000177213210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx662] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.000"}} 1800000013640000000000000000000000000000003a3000 1800000013640000000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-083.phpt0000664000175000017500000000205313210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx297] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000038b000 {"d":{"$numberDecimal":"-0.0000"}} 18000000136400000000000000000000000000000038b000 18000000136400000000000000000000000000000038b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-084.phpt0000664000175000017500000000177013210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx643] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000443000 {"d":{"$numberDecimal":"0E+2"}} 180000001364000000000000000000000000000000443000 180000001364000000000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-085.phpt0000664000175000017500000000177413210321137022717 0ustar jmikolajmikola--TEST-- Decimal128: [basx663] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000383000 {"d":{"$numberDecimal":"0.0000"}} 180000001364000000000000000000000000000000383000 180000001364000000000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-086.phpt0000664000175000017500000000177013210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [basx644] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000463000 {"d":{"$numberDecimal":"0E+3"}} 180000001364000000000000000000000000000000463000 180000001364000000000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-087.phpt0000664000175000017500000000177613210321137022723 0ustar jmikolajmikola--TEST-- Decimal128: [basx664] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000363000 {"d":{"$numberDecimal":"0.00000"}} 180000001364000000000000000000000000000000363000 180000001364000000000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-088.phpt0000664000175000017500000000177013210321137022716 0ustar jmikolajmikola--TEST-- Decimal128: [basx645] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000483000 {"d":{"$numberDecimal":"0E+4"}} 180000001364000000000000000000000000000000483000 180000001364000000000000000000000000000000483000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-089.phpt0000664000175000017500000000200013210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx665] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000343000 {"d":{"$numberDecimal":"0.000000"}} 180000001364000000000000000000000000000000343000 180000001364000000000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-090.phpt0000664000175000017500000000177013210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx646] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004a3000 {"d":{"$numberDecimal":"0E+5"}} 1800000013640000000000000000000000000000004a3000 1800000013640000000000000000000000000000004a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-091.phpt0000664000175000017500000000177013210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx666] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000323000 {"d":{"$numberDecimal":"0E-7"}} 180000001364000000000000000000000000000000323000 180000001364000000000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-092.phpt0000664000175000017500000000177013210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx647] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004c3000 {"d":{"$numberDecimal":"0E+6"}} 1800000013640000000000000000000000000000004c3000 1800000013640000000000000000000000000000004c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-093.phpt0000664000175000017500000000177013210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx667] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000303000 {"d":{"$numberDecimal":"0E-8"}} 180000001364000000000000000000000000000000303000 180000001364000000000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-094.phpt0000664000175000017500000000177013210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx648] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004e3000 {"d":{"$numberDecimal":"0E+7"}} 1800000013640000000000000000000000000000004e3000 1800000013640000000000000000000000000000004e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-095.phpt0000664000175000017500000000177013210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [basx668] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002e3000 {"d":{"$numberDecimal":"0E-9"}} 1800000013640000000000000000000000000000002e3000 1800000013640000000000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-096.phpt0000664000175000017500000000200013210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx160] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000523000 {"d":{"$numberDecimal":"0E+9"}} 180000001364000000000000000000000000000000523000 180000001364000000000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-097.phpt0000664000175000017500000000200013210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx161] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002e3000 {"d":{"$numberDecimal":"0E-9"}} 1800000013640000000000000000000000000000002e3000 1800000013640000000000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-098.phpt0000664000175000017500000000177013210321137022717 0ustar jmikolajmikola--TEST-- Decimal128: [basx649] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000503000 {"d":{"$numberDecimal":"0E+8"}} 180000001364000000000000000000000000000000503000 180000001364000000000000000000000000000000503000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-099.phpt0000664000175000017500000000177213210321137022722 0ustar jmikolajmikola--TEST-- Decimal128: [basx669] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000002c3000 {"d":{"$numberDecimal":"0E-10"}} 1800000013640000000000000000000000000000002c3000 1800000013640000000000000000000000000000002c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-100.phpt0000664000175000017500000000206513210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx062] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400185c0ace00000000000000000000383000 {"d":{"$numberDecimal":"345678.5432"}} 18000000136400185c0ace00000000000000000000383000 18000000136400185c0ace00000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-101.phpt0000664000175000017500000000153413210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx001] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-102.phpt0000664000175000017500000000153613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx017] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000040b000 {"d":{"$numberDecimal":"-0"}} 18000000136400000000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-103.phpt0000664000175000017500000000175613210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx611] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-104.phpt0000664000175000017500000000176113210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx613] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000040b000 {"d":{"$numberDecimal":"-0"}} 18000000136400000000000000000000000000000040b000 18000000136400000000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-105.phpt0000664000175000017500000000175613210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx685] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-106.phpt0000664000175000017500000000175713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx688] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-107.phpt0000664000175000017500000000176113210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx689] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000040b000 {"d":{"$numberDecimal":"-0"}} 18000000136400000000000000000000000000000040b000 18000000136400000000000000000000000000000040b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-108.phpt0000664000175000017500000000176013210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx650] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000403000 {"d":{"$numberDecimal":"0"}} 180000001364000000000000000000000000000000403000 180000001364000000000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-109.phpt0000664000175000017500000000145513210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx651] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000423000 {"d":{"$numberDecimal":"0E+1"}} 180000001364000000000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-110.phpt0000664000175000017500000000204513210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx298] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003cb000 {"d":{"$numberDecimal":"-0.00"}} 1800000013640000000000000000000000000000003cb000 1800000013640000000000000000000000000000003cb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-111.phpt0000664000175000017500000000145513210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx652] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000443000 {"d":{"$numberDecimal":"0E+2"}} 180000001364000000000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-112.phpt0000664000175000017500000000204713210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx299] some more negative zeros [systematic tests below] --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003ab000 {"d":{"$numberDecimal":"-0.000"}} 1800000013640000000000000000000000000000003ab000 1800000013640000000000000000000000000000003ab000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-113.phpt0000664000175000017500000000145513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx653] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000463000 {"d":{"$numberDecimal":"0E+3"}} 180000001364000000000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-114.phpt0000664000175000017500000000145513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx654] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000483000 {"d":{"$numberDecimal":"0E+4"}} 180000001364000000000000000000000000000000483000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-115.phpt0000664000175000017500000000145513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx655] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004a3000 {"d":{"$numberDecimal":"0E+5"}} 1800000013640000000000000000000000000000004a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-116.phpt0000664000175000017500000000145513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx656] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004c3000 {"d":{"$numberDecimal":"0E+6"}} 1800000013640000000000000000000000000000004c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-117.phpt0000664000175000017500000000145513210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx657] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000004e3000 {"d":{"$numberDecimal":"0E+7"}} 1800000013640000000000000000000000000000004e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-118.phpt0000664000175000017500000000145513210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx658] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000503000 {"d":{"$numberDecimal":"0E+8"}} 180000001364000000000000000000000000000000503000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-119.phpt0000664000175000017500000000200013210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx138] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000523000 {"d":{"$numberDecimal":"0E+9"}} 180000001364000000000000000000000000000000523000 180000001364000000000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-120.phpt0000664000175000017500000000147013210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx139] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000000000000000000000052b000 {"d":{"$numberDecimal":"-0E+9"}} 18000000136400000000000000000000000000000052b000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-121.phpt0000664000175000017500000000146613210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx144] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000523000 {"d":{"$numberDecimal":"0E+9"}} 180000001364000000000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-122.phpt0000664000175000017500000000177613210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx154] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000523000 {"d":{"$numberDecimal":"0E+9"}} 180000001364000000000000000000000000000000523000 180000001364000000000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-123.phpt0000664000175000017500000000145513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx659] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000523000 {"d":{"$numberDecimal":"0E+9"}} 180000001364000000000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-124.phpt0000664000175000017500000000204213210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx042] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400fc040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.76"}} 18000000136400fc040000000000000000000000003c3000 18000000136400fc040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-125.phpt0000664000175000017500000000200213210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx143] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-126.phpt0000664000175000017500000000206413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx061] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400185c0ace00000000000000000000383000 {"d":{"$numberDecimal":"345678.5432"}} 18000000136400185c0ace00000000000000000000383000 18000000136400185c0ace00000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-127.phpt0000664000175000017500000000211313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx036] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640015cd5b0700000000000000000000203000 {"d":{"$numberDecimal":"1.23456789E-8"}} 1800000013640015cd5b0700000000000000000000203000 1800000013640015cd5b0700000000000000000000203000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-128.phpt0000664000175000017500000000211213210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx035] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640015cd5b0700000000000000000000223000 {"d":{"$numberDecimal":"1.23456789E-7"}} 1800000013640015cd5b0700000000000000000000223000 1800000013640015cd5b0700000000000000000000223000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-129.phpt0000664000175000017500000000157213210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx034] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640015cd5b0700000000000000000000243000 {"d":{"$numberDecimal":"0.00000123456789"}} 1800000013640015cd5b0700000000000000000000243000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-130.phpt0000664000175000017500000000153713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx053] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003200000000000000000000000000323000 {"d":{"$numberDecimal":"0.0000050"}} 180000001364003200000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-131.phpt0000664000175000017500000000157013210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx033] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640015cd5b0700000000000000000000263000 {"d":{"$numberDecimal":"0.0000123456789"}} 1800000013640015cd5b0700000000000000000000263000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-132.phpt0000664000175000017500000000154413210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx016] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000c000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.012"}} 180000001364000c000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-133.phpt0000664000175000017500000000154413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx015] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364007b000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.123"}} 180000001364007b000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-134.phpt0000664000175000017500000000157413210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx037] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640078df0d8648700000000000000000223000 {"d":{"$numberDecimal":"0.123456789012344"}} 1800000013640078df0d8648700000000000000000223000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-135.phpt0000664000175000017500000000157413210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx038] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640079df0d8648700000000000000000223000 {"d":{"$numberDecimal":"0.123456789012345"}} 1800000013640079df0d8648700000000000000000223000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-136.phpt0000664000175000017500000000147213210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx250] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000383000 {"d":{"$numberDecimal":"0.1265"}} 18000000136400f104000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-137.phpt0000664000175000017500000000201013210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx257] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000383000 {"d":{"$numberDecimal":"0.1265"}} 18000000136400f104000000000000000000000000383000 18000000136400f104000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-138.phpt0000664000175000017500000000201213210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx256] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000363000 {"d":{"$numberDecimal":"0.01265"}} 18000000136400f104000000000000000000000000363000 18000000136400f104000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-139.phpt0000664000175000017500000000200613210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx258] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003a3000 {"d":{"$numberDecimal":"1.265"}} 18000000136400f1040000000000000000000000003a3000 18000000136400f1040000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-140.phpt0000664000175000017500000000201713210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx251] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000103000 {"d":{"$numberDecimal":"1.265E-21"}} 18000000136400f104000000000000000000000000103000 18000000136400f104000000000000000000000000103000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-141.phpt0000664000175000017500000000201713210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx263] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000603000 {"d":{"$numberDecimal":"1.265E+19"}} 18000000136400f104000000000000000000000000603000 18000000136400f104000000000000000000000000603000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-142.phpt0000664000175000017500000000201413210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx255] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000343000 {"d":{"$numberDecimal":"0.001265"}} 18000000136400f104000000000000000000000000343000 18000000136400f104000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-143.phpt0000664000175000017500000000200613210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx259] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.65"}} 18000000136400f1040000000000000000000000003c3000 18000000136400f1040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-144.phpt0000664000175000017500000000201613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx254] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000323000 {"d":{"$numberDecimal":"0.0001265"}} 18000000136400f104000000000000000000000000323000 18000000136400f104000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-145.phpt0000664000175000017500000000200613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx260] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003e3000 {"d":{"$numberDecimal":"126.5"}} 18000000136400f1040000000000000000000000003e3000 18000000136400f1040000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-146.phpt0000664000175000017500000000202013210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx253] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000303000 {"d":{"$numberDecimal":"0.00001265"}} 18000000136400f104000000000000000000000000303000 18000000136400f104000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-147.phpt0000664000175000017500000000200413210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx261] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000403000 {"d":{"$numberDecimal":"1265"}} 18000000136400f104000000000000000000000000403000 18000000136400f104000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-148.phpt0000664000175000017500000000201413210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx252] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000283000 {"d":{"$numberDecimal":"1.265E-9"}} 18000000136400f104000000000000000000000000283000 18000000136400f104000000000000000000000000283000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-149.phpt0000664000175000017500000000201413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx262] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000483000 {"d":{"$numberDecimal":"1.265E+7"}} 18000000136400f104000000000000000000000000483000 18000000136400f104000000000000000000000000483000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-150.phpt0000664000175000017500000000200613210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx159] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640049000000000000000000000000002e3000 {"d":{"$numberDecimal":"7.3E-8"}} 1800000013640049000000000000000000000000002e3000 1800000013640049000000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-151.phpt0000664000175000017500000000154213210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx004] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640064000000000000000000000000003c3000 {"d":{"$numberDecimal":"1.00"}} 1800000013640064000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-152.phpt0000664000175000017500000000154013210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx003] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000003e3000 {"d":{"$numberDecimal":"1.0"}} 180000001364000a000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-153.phpt0000664000175000017500000000153413210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx002] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000403000 {"d":{"$numberDecimal":"1"}} 180000001364000100000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-154.phpt0000664000175000017500000000200113210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx148] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-155.phpt0000664000175000017500000000200013210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx153] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-156.phpt0000664000175000017500000000200013210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx141] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-157.phpt0000664000175000017500000000200013210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx146] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-158.phpt0000664000175000017500000000177713210321137022723 0ustar jmikolajmikola--TEST-- Decimal128: [basx151] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-159.phpt0000664000175000017500000000147013210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx142] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000f43000 {"d":{"$numberDecimal":"1E+90"}} 180000001364000100000000000000000000000000f43000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-160.phpt0000664000175000017500000000200213210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: [basx147] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000f43000 {"d":{"$numberDecimal":"1E+90"}} 180000001364000100000000000000000000000000f43000 180000001364000100000000000000000000000000f43000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-161.phpt0000664000175000017500000000200113210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: [basx152] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000f43000 {"d":{"$numberDecimal":"1E+90"}} 180000001364000100000000000000000000000000f43000 180000001364000100000000000000000000000000f43000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-162.phpt0000664000175000017500000000146613210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx140] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-163.phpt0000664000175000017500000000177613210321137022716 0ustar jmikolajmikola--TEST-- Decimal128: [basx150] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000523000 {"d":{"$numberDecimal":"1E+9"}} 180000001364000100000000000000000000000000523000 180000001364000100000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-164.phpt0000664000175000017500000000154413210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx014] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400d2040000000000000000000000003a3000 {"d":{"$numberDecimal":"1.234"}} 18000000136400d2040000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-165.phpt0000664000175000017500000000147013210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx170] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003a3000 {"d":{"$numberDecimal":"1.265"}} 18000000136400f1040000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-166.phpt0000664000175000017500000000200513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx177] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003a3000 {"d":{"$numberDecimal":"1.265"}} 18000000136400f1040000000000000000000000003a3000 18000000136400f1040000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-167.phpt0000664000175000017500000000200713210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx176] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000383000 {"d":{"$numberDecimal":"0.1265"}} 18000000136400f104000000000000000000000000383000 18000000136400f104000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-168.phpt0000664000175000017500000000200513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx178] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.65"}} 18000000136400f1040000000000000000000000003c3000 18000000136400f1040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-169.phpt0000664000175000017500000000150013210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx171] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000123000 {"d":{"$numberDecimal":"1.265E-20"}} 18000000136400f104000000000000000000000000123000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-170.phpt0000664000175000017500000000150013210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx183] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000623000 {"d":{"$numberDecimal":"1.265E+20"}} 18000000136400f104000000000000000000000000623000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-171.phpt0000664000175000017500000000201113210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx175] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000363000 {"d":{"$numberDecimal":"0.01265"}} 18000000136400f104000000000000000000000000363000 18000000136400f104000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-172.phpt0000664000175000017500000000200513210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx179] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003e3000 {"d":{"$numberDecimal":"126.5"}} 18000000136400f1040000000000000000000000003e3000 18000000136400f1040000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-173.phpt0000664000175000017500000000201313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx174] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000343000 {"d":{"$numberDecimal":"0.001265"}} 18000000136400f104000000000000000000000000343000 18000000136400f104000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-174.phpt0000664000175000017500000000200313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx180] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000403000 {"d":{"$numberDecimal":"1265"}} 18000000136400f104000000000000000000000000403000 18000000136400f104000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-175.phpt0000664000175000017500000000201513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx173] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000323000 {"d":{"$numberDecimal":"0.0001265"}} 18000000136400f104000000000000000000000000323000 18000000136400f104000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-176.phpt0000664000175000017500000000147613210321137022717 0ustar jmikolajmikola--TEST-- Decimal128: [basx181] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000423000 {"d":{"$numberDecimal":"1.265E+4"}} 18000000136400f104000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-177.phpt0000664000175000017500000000147613210321137022720 0ustar jmikolajmikola--TEST-- Decimal128: [basx172] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000002a3000 {"d":{"$numberDecimal":"1.265E-8"}} 18000000136400f1040000000000000000000000002a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-178.phpt0000664000175000017500000000147613210321137022721 0ustar jmikolajmikola--TEST-- Decimal128: [basx182] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000004a3000 {"d":{"$numberDecimal":"1.265E+8"}} 18000000136400f1040000000000000000000000004a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-179.phpt0000664000175000017500000000146613210321137022721 0ustar jmikolajmikola--TEST-- Decimal128: [basx157] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000400000000000000000000000000523000 {"d":{"$numberDecimal":"4E+9"}} 180000001364000400000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-180.phpt0000664000175000017500000000200113210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx067] examples --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000500000000000000000000000000343000 {"d":{"$numberDecimal":"0.000005"}} 180000001364000500000000000000000000000000343000 180000001364000500000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-181.phpt0000664000175000017500000000146013210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx069] examples --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000500000000000000000000000000323000 {"d":{"$numberDecimal":"5E-7"}} 180000001364000500000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-182.phpt0000664000175000017500000000200413210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx385] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000403000 {"d":{"$numberDecimal":"7"}} 180000001364000700000000000000000000000000403000 180000001364000700000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-183.phpt0000664000175000017500000000201513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx365] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000543000 {"d":{"$numberDecimal":"7E+10"}} 180000001364000700000000000000000000000000543000 180000001364000700000000000000000000000000543000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-184.phpt0000664000175000017500000000150413210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx405] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000002c3000 {"d":{"$numberDecimal":"7E-10"}} 1800000013640007000000000000000000000000002c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-185.phpt0000664000175000017500000000201513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx363] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000563000 {"d":{"$numberDecimal":"7E+11"}} 180000001364000700000000000000000000000000563000 180000001364000700000000000000000000000000563000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-186.phpt0000664000175000017500000000150413210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx407] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000002a3000 {"d":{"$numberDecimal":"7E-11"}} 1800000013640007000000000000000000000000002a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-187.phpt0000664000175000017500000000201513210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx361] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000583000 {"d":{"$numberDecimal":"7E+12"}} 180000001364000700000000000000000000000000583000 180000001364000700000000000000000000000000583000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-188.phpt0000664000175000017500000000150413210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx409] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000283000 {"d":{"$numberDecimal":"7E-12"}} 180000001364000700000000000000000000000000283000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-189.phpt0000664000175000017500000000150413210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx411] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000263000 {"d":{"$numberDecimal":"7E-13"}} 180000001364000700000000000000000000000000263000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-190.phpt0000664000175000017500000000201213210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx383] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000423000 {"d":{"$numberDecimal":"7E+1"}} 180000001364000700000000000000000000000000423000 180000001364000700000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-191.phpt0000664000175000017500000000201113210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx387] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.7"}} 1800000013640007000000000000000000000000003e3000 1800000013640007000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-192.phpt0000664000175000017500000000201213210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx381] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000443000 {"d":{"$numberDecimal":"7E+2"}} 180000001364000700000000000000000000000000443000 180000001364000700000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-193.phpt0000664000175000017500000000201313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx389] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.07"}} 1800000013640007000000000000000000000000003c3000 1800000013640007000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-194.phpt0000664000175000017500000000201213210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx379] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000463000 {"d":{"$numberDecimal":"7E+3"}} 180000001364000700000000000000000000000000463000 180000001364000700000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-195.phpt0000664000175000017500000000201513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx391] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.007"}} 1800000013640007000000000000000000000000003a3000 1800000013640007000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-196.phpt0000664000175000017500000000201213210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx377] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000483000 {"d":{"$numberDecimal":"7E+4"}} 180000001364000700000000000000000000000000483000 180000001364000700000000000000000000000000483000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-197.phpt0000664000175000017500000000201713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [basx393] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000383000 {"d":{"$numberDecimal":"0.0007"}} 180000001364000700000000000000000000000000383000 180000001364000700000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-198.phpt0000664000175000017500000000201213210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx375] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000004a3000 {"d":{"$numberDecimal":"7E+5"}} 1800000013640007000000000000000000000000004a3000 1800000013640007000000000000000000000000004a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-199.phpt0000664000175000017500000000202113210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx395] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000363000 {"d":{"$numberDecimal":"0.00007"}} 180000001364000700000000000000000000000000363000 180000001364000700000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-200.phpt0000664000175000017500000000201213210321137022666 0ustar jmikolajmikola--TEST-- Decimal128: [basx373] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000004c3000 {"d":{"$numberDecimal":"7E+6"}} 1800000013640007000000000000000000000000004c3000 1800000013640007000000000000000000000000004c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-201.phpt0000664000175000017500000000202313210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [basx397] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000343000 {"d":{"$numberDecimal":"0.000007"}} 180000001364000700000000000000000000000000343000 180000001364000700000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-202.phpt0000664000175000017500000000201213210321137022670 0ustar jmikolajmikola--TEST-- Decimal128: [basx371] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000004e3000 {"d":{"$numberDecimal":"7E+7"}} 1800000013640007000000000000000000000000004e3000 1800000013640007000000000000000000000000004e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-203.phpt0000664000175000017500000000150213210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx399] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000323000 {"d":{"$numberDecimal":"7E-7"}} 180000001364000700000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-204.phpt0000664000175000017500000000201213210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: [basx369] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000503000 {"d":{"$numberDecimal":"7E+8"}} 180000001364000700000000000000000000000000503000 180000001364000700000000000000000000000000503000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-205.phpt0000664000175000017500000000150213210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx401] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000303000 {"d":{"$numberDecimal":"7E-8"}} 180000001364000700000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-206.phpt0000664000175000017500000000201213210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx367] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000700000000000000000000000000523000 {"d":{"$numberDecimal":"7E+9"}} 180000001364000700000000000000000000000000523000 180000001364000700000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-207.phpt0000664000175000017500000000150213210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx403] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640007000000000000000000000000002e3000 {"d":{"$numberDecimal":"7E-9"}} 1800000013640007000000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-208.phpt0000664000175000017500000000154213210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx007] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640064000000000000000000000000003e3000 {"d":{"$numberDecimal":"10.0"}} 1800000013640064000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-209.phpt0000664000175000017500000000153613210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx005] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000403000 {"d":{"$numberDecimal":"10"}} 180000001364000a00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-210.phpt0000664000175000017500000000201013210321137022665 0ustar jmikolajmikola--TEST-- Decimal128: [basx165] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000523000 {"d":{"$numberDecimal":"1.0E+10"}} 180000001364000a00000000000000000000000000523000 180000001364000a00000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-211.phpt0000664000175000017500000000200713210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [basx163] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000523000 {"d":{"$numberDecimal":"1.0E+10"}} 180000001364000a00000000000000000000000000523000 180000001364000a00000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-212.phpt0000664000175000017500000000200713210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx325] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000403000 {"d":{"$numberDecimal":"10"}} 180000001364000a00000000000000000000000000403000 180000001364000a00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-213.phpt0000664000175000017500000000202213210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx305] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000543000 {"d":{"$numberDecimal":"1.0E+11"}} 180000001364000a00000000000000000000000000543000 180000001364000a00000000000000000000000000543000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-214.phpt0000664000175000017500000000202113210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx345] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000002c3000 {"d":{"$numberDecimal":"1.0E-9"}} 180000001364000a000000000000000000000000002c3000 180000001364000a000000000000000000000000002c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-215.phpt0000664000175000017500000000202213210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx303] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000563000 {"d":{"$numberDecimal":"1.0E+12"}} 180000001364000a00000000000000000000000000563000 180000001364000a00000000000000000000000000563000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-216.phpt0000664000175000017500000000202313210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx347] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000002a3000 {"d":{"$numberDecimal":"1.0E-10"}} 180000001364000a000000000000000000000000002a3000 180000001364000a000000000000000000000000002a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-217.phpt0000664000175000017500000000202213210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx301] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000583000 {"d":{"$numberDecimal":"1.0E+13"}} 180000001364000a00000000000000000000000000583000 180000001364000a00000000000000000000000000583000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-218.phpt0000664000175000017500000000202313210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx349] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000283000 {"d":{"$numberDecimal":"1.0E-11"}} 180000001364000a00000000000000000000000000283000 180000001364000a00000000000000000000000000283000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-219.phpt0000664000175000017500000000202313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx351] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000263000 {"d":{"$numberDecimal":"1.0E-12"}} 180000001364000a00000000000000000000000000263000 180000001364000a00000000000000000000000000263000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-220.phpt0000664000175000017500000000201713210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx323] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000423000 {"d":{"$numberDecimal":"1.0E+2"}} 180000001364000a00000000000000000000000000423000 180000001364000a00000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-221.phpt0000664000175000017500000000201213210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [basx327] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000003e3000 {"d":{"$numberDecimal":"1.0"}} 180000001364000a000000000000000000000000003e3000 180000001364000a000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-222.phpt0000664000175000017500000000201713210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx321] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000443000 {"d":{"$numberDecimal":"1.0E+3"}} 180000001364000a00000000000000000000000000443000 180000001364000a00000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-223.phpt0000664000175000017500000000201413210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx329] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000003c3000 {"d":{"$numberDecimal":"0.10"}} 180000001364000a000000000000000000000000003c3000 180000001364000a000000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-224.phpt0000664000175000017500000000201713210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx319] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000463000 {"d":{"$numberDecimal":"1.0E+4"}} 180000001364000a00000000000000000000000000463000 180000001364000a00000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-225.phpt0000664000175000017500000000201613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx331] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.010"}} 180000001364000a000000000000000000000000003a3000 180000001364000a000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-226.phpt0000664000175000017500000000201713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx317] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000483000 {"d":{"$numberDecimal":"1.0E+5"}} 180000001364000a00000000000000000000000000483000 180000001364000a00000000000000000000000000483000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-227.phpt0000664000175000017500000000202013210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx333] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000383000 {"d":{"$numberDecimal":"0.0010"}} 180000001364000a00000000000000000000000000383000 180000001364000a00000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-228.phpt0000664000175000017500000000201713210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx315] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000004a3000 {"d":{"$numberDecimal":"1.0E+6"}} 180000001364000a000000000000000000000000004a3000 180000001364000a000000000000000000000000004a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-229.phpt0000664000175000017500000000202213210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx335] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000363000 {"d":{"$numberDecimal":"0.00010"}} 180000001364000a00000000000000000000000000363000 180000001364000a00000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-230.phpt0000664000175000017500000000201713210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [basx313] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000004c3000 {"d":{"$numberDecimal":"1.0E+7"}} 180000001364000a000000000000000000000000004c3000 180000001364000a000000000000000000000000004c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-231.phpt0000664000175000017500000000202413210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx337] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000343000 {"d":{"$numberDecimal":"0.000010"}} 180000001364000a00000000000000000000000000343000 180000001364000a00000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-232.phpt0000664000175000017500000000201713210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx311] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000004e3000 {"d":{"$numberDecimal":"1.0E+8"}} 180000001364000a000000000000000000000000004e3000 180000001364000a000000000000000000000000004e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-233.phpt0000664000175000017500000000202613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx339] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000323000 {"d":{"$numberDecimal":"0.0000010"}} 180000001364000a00000000000000000000000000323000 180000001364000a00000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-234.phpt0000664000175000017500000000201713210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx309] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000503000 {"d":{"$numberDecimal":"1.0E+9"}} 180000001364000a00000000000000000000000000503000 180000001364000a00000000000000000000000000503000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-235.phpt0000664000175000017500000000202013210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx341] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000303000 {"d":{"$numberDecimal":"1.0E-7"}} 180000001364000a00000000000000000000000000303000 180000001364000a00000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-236.phpt0000664000175000017500000000200713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx164] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000f43000 {"d":{"$numberDecimal":"1.0E+91"}} 180000001364000a00000000000000000000000000f43000 180000001364000a00000000000000000000000000f43000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-237.phpt0000664000175000017500000000200613210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx162] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000523000 {"d":{"$numberDecimal":"1.0E+10"}} 180000001364000a00000000000000000000000000523000 180000001364000a00000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-238.phpt0000664000175000017500000000202113210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx307] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000523000 {"d":{"$numberDecimal":"1.0E+10"}} 180000001364000a00000000000000000000000000523000 180000001364000a00000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-239.phpt0000664000175000017500000000202013210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx343] Engineering notation tests --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a000000000000000000000000002e3000 {"d":{"$numberDecimal":"1.0E-8"}} 180000001364000a000000000000000000000000002e3000 180000001364000a000000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-240.phpt0000664000175000017500000000154213210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx008] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640065000000000000000000000000003e3000 {"d":{"$numberDecimal":"10.1"}} 1800000013640065000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-241.phpt0000664000175000017500000000154213210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx009] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640068000000000000000000000000003e3000 {"d":{"$numberDecimal":"10.4"}} 1800000013640068000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-242.phpt0000664000175000017500000000154213210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx010] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640069000000000000000000000000003e3000 {"d":{"$numberDecimal":"10.5"}} 1800000013640069000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-243.phpt0000664000175000017500000000154213210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx011] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006a000000000000000000000000003e3000 {"d":{"$numberDecimal":"10.6"}} 180000001364006a000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-244.phpt0000664000175000017500000000154213210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx012] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006d000000000000000000000000003e3000 {"d":{"$numberDecimal":"10.9"}} 180000001364006d000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-245.phpt0000664000175000017500000000154213210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx013] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006e000000000000000000000000003e3000 {"d":{"$numberDecimal":"11.0"}} 180000001364006e000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-246.phpt0000664000175000017500000000152113210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx040] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000c00000000000000000000000000403000 {"d":{"$numberDecimal":"12"}} 180000001364000c00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-247.phpt0000664000175000017500000000147013210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx190] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.65"}} 18000000136400f1040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-248.phpt0000664000175000017500000000200513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx197] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.65"}} 18000000136400f1040000000000000000000000003c3000 18000000136400f1040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-249.phpt0000664000175000017500000000200513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx196] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003a3000 {"d":{"$numberDecimal":"1.265"}} 18000000136400f1040000000000000000000000003a3000 18000000136400f1040000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-250.phpt0000664000175000017500000000200513210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx198] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003e3000 {"d":{"$numberDecimal":"126.5"}} 18000000136400f1040000000000000000000000003e3000 18000000136400f1040000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-251.phpt0000664000175000017500000000201613210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx191] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000143000 {"d":{"$numberDecimal":"1.265E-19"}} 18000000136400f104000000000000000000000000143000 18000000136400f104000000000000000000000000143000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-252.phpt0000664000175000017500000000201613210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [basx203] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000643000 {"d":{"$numberDecimal":"1.265E+21"}} 18000000136400f104000000000000000000000000643000 18000000136400f104000000000000000000000000643000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-253.phpt0000664000175000017500000000200713210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx195] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000383000 {"d":{"$numberDecimal":"0.1265"}} 18000000136400f104000000000000000000000000383000 18000000136400f104000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-254.phpt0000664000175000017500000000200313210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx199] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000403000 {"d":{"$numberDecimal":"1265"}} 18000000136400f104000000000000000000000000403000 18000000136400f104000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-255.phpt0000664000175000017500000000201113210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx194] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000363000 {"d":{"$numberDecimal":"0.01265"}} 18000000136400f104000000000000000000000000363000 18000000136400f104000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-256.phpt0000664000175000017500000000201313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx200] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000423000 {"d":{"$numberDecimal":"1.265E+4"}} 18000000136400f104000000000000000000000000423000 18000000136400f104000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-257.phpt0000664000175000017500000000201313210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx193] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000343000 {"d":{"$numberDecimal":"0.001265"}} 18000000136400f104000000000000000000000000343000 18000000136400f104000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-258.phpt0000664000175000017500000000201313210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx201] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000443000 {"d":{"$numberDecimal":"1.265E+5"}} 18000000136400f104000000000000000000000000443000 18000000136400f104000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-259.phpt0000664000175000017500000000201313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx192] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000002c3000 {"d":{"$numberDecimal":"1.265E-7"}} 18000000136400f1040000000000000000000000002c3000 18000000136400f1040000000000000000000000002c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-260.phpt0000664000175000017500000000201313210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx202] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000004c3000 {"d":{"$numberDecimal":"1.265E+9"}} 18000000136400f1040000000000000000000000004c3000 18000000136400f1040000000000000000000000004c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-261.phpt0000664000175000017500000000204213210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx044] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400fc040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.76"}} 18000000136400fc040000000000000000000000003c3000 18000000136400fc040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-262.phpt0000664000175000017500000000152713210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx042] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400fc040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.76"}} 18000000136400fc040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-263.phpt0000664000175000017500000000203113210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx046] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001100000000000000000000000000403000 {"d":{"$numberDecimal":"17"}} 180000001364001100000000000000000000000000403000 180000001364001100000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-264.phpt0000664000175000017500000000203213210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx049] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364002c00000000000000000000000000403000 {"d":{"$numberDecimal":"44"}} 180000001364002c00000000000000000000000000403000 180000001364002c00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-265.phpt0000664000175000017500000000203113210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx048] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364002c00000000000000000000000000403000 {"d":{"$numberDecimal":"44"}} 180000001364002c00000000000000000000000000403000 180000001364002c00000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-266.phpt0000664000175000017500000000200613210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx158] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364002c00000000000000000000000000523000 {"d":{"$numberDecimal":"4.4E+10"}} 180000001364002c00000000000000000000000000523000 180000001364002c00000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-267.phpt0000664000175000017500000000200413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx068] examples --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364003200000000000000000000000000323000 {"d":{"$numberDecimal":"0.0000050"}} 180000001364003200000000000000000000000000323000 180000001364003200000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-268.phpt0000664000175000017500000000201313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx169] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006400000000000000000000000000523000 {"d":{"$numberDecimal":"1.00E+11"}} 180000001364006400000000000000000000000000523000 180000001364006400000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-269.phpt0000664000175000017500000000201213210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx167] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006400000000000000000000000000523000 {"d":{"$numberDecimal":"1.00E+11"}} 180000001364006400000000000000000000000000523000 180000001364006400000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-270.phpt0000664000175000017500000000201213210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx168] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006400000000000000000000000000f43000 {"d":{"$numberDecimal":"1.00E+92"}} 180000001364006400000000000000000000000000f43000 180000001364006400000000000000000000000000f43000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-271.phpt0000664000175000017500000000201113210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx166] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006400000000000000000000000000523000 {"d":{"$numberDecimal":"1.00E+11"}} 180000001364006400000000000000000000000000523000 180000001364006400000000000000000000000000523000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-272.phpt0000664000175000017500000000147013210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx210] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003e3000 {"d":{"$numberDecimal":"126.5"}} 18000000136400f1040000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-273.phpt0000664000175000017500000000200513210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx217] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003e3000 {"d":{"$numberDecimal":"126.5"}} 18000000136400f1040000000000000000000000003e3000 18000000136400f1040000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-274.phpt0000664000175000017500000000200513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx216] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.65"}} 18000000136400f1040000000000000000000000003c3000 18000000136400f1040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-275.phpt0000664000175000017500000000200313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx218] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000403000 {"d":{"$numberDecimal":"1265"}} 18000000136400f104000000000000000000000000403000 18000000136400f104000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-276.phpt0000664000175000017500000000201613210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx211] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000163000 {"d":{"$numberDecimal":"1.265E-18"}} 18000000136400f104000000000000000000000000163000 18000000136400f104000000000000000000000000163000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-277.phpt0000664000175000017500000000201613210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx223] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000663000 {"d":{"$numberDecimal":"1.265E+22"}} 18000000136400f104000000000000000000000000663000 18000000136400f104000000000000000000000000663000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-278.phpt0000664000175000017500000000200513210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx215] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003a3000 {"d":{"$numberDecimal":"1.265"}} 18000000136400f1040000000000000000000000003a3000 18000000136400f1040000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-279.phpt0000664000175000017500000000201313210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx219] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000423000 {"d":{"$numberDecimal":"1.265E+4"}} 18000000136400f104000000000000000000000000423000 18000000136400f104000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-280.phpt0000664000175000017500000000200713210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx214] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000383000 {"d":{"$numberDecimal":"0.1265"}} 18000000136400f104000000000000000000000000383000 18000000136400f104000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-281.phpt0000664000175000017500000000201313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx220] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000443000 {"d":{"$numberDecimal":"1.265E+5"}} 18000000136400f104000000000000000000000000443000 18000000136400f104000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-282.phpt0000664000175000017500000000201113210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx213] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000363000 {"d":{"$numberDecimal":"0.01265"}} 18000000136400f104000000000000000000000000363000 18000000136400f104000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-283.phpt0000664000175000017500000000201313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx221] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000463000 {"d":{"$numberDecimal":"1.265E+6"}} 18000000136400f104000000000000000000000000463000 18000000136400f104000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-284.phpt0000664000175000017500000000202113210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx212] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000002e3000 {"d":{"$numberDecimal":"0.000001265"}} 18000000136400f1040000000000000000000000002e3000 18000000136400f1040000000000000000000000002e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-285.phpt0000664000175000017500000000201513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx222] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000004e3000 {"d":{"$numberDecimal":"1.265E+10"}} 18000000136400f1040000000000000000000000004e3000 18000000136400f1040000000000000000000000004e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-286.phpt0000664000175000017500000000154213210321137022713 0ustar jmikolajmikola--TEST-- Decimal128: [basx006] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e803000000000000000000000000403000 {"d":{"$numberDecimal":"1000"}} 18000000136400e803000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-287.phpt0000664000175000017500000000146613210321137022721 0ustar jmikolajmikola--TEST-- Decimal128: [basx230] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000403000 {"d":{"$numberDecimal":"1265"}} 18000000136400f104000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-288.phpt0000664000175000017500000000200213210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx237] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000403000 {"d":{"$numberDecimal":"1265"}} 18000000136400f104000000000000000000000000403000 18000000136400f104000000000000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-289.phpt0000664000175000017500000000200413210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx236] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003e3000 {"d":{"$numberDecimal":"126.5"}} 18000000136400f1040000000000000000000000003e3000 18000000136400f1040000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-290.phpt0000664000175000017500000000201213210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [basx238] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000423000 {"d":{"$numberDecimal":"1.265E+4"}} 18000000136400f104000000000000000000000000423000 18000000136400f104000000000000000000000000423000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-291.phpt0000664000175000017500000000201513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx231] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000183000 {"d":{"$numberDecimal":"1.265E-17"}} 18000000136400f104000000000000000000000000183000 18000000136400f104000000000000000000000000183000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-292.phpt0000664000175000017500000000201513210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [basx243] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000683000 {"d":{"$numberDecimal":"1.265E+23"}} 18000000136400f104000000000000000000000000683000 18000000136400f104000000000000000000000000683000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-293.phpt0000664000175000017500000000200413210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx235] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.65"}} 18000000136400f1040000000000000000000000003c3000 18000000136400f1040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-294.phpt0000664000175000017500000000201213210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx239] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000443000 {"d":{"$numberDecimal":"1.265E+5"}} 18000000136400f104000000000000000000000000443000 18000000136400f104000000000000000000000000443000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-295.phpt0000664000175000017500000000200413210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx234] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f1040000000000000000000000003a3000 {"d":{"$numberDecimal":"1.265"}} 18000000136400f1040000000000000000000000003a3000 18000000136400f1040000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-296.phpt0000664000175000017500000000201213210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx240] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000463000 {"d":{"$numberDecimal":"1.265E+6"}} 18000000136400f104000000000000000000000000463000 18000000136400f104000000000000000000000000463000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-297.phpt0000664000175000017500000000200613210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [basx233] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000383000 {"d":{"$numberDecimal":"0.1265"}} 18000000136400f104000000000000000000000000383000 18000000136400f104000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-298.phpt0000664000175000017500000000201213210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx241] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000483000 {"d":{"$numberDecimal":"1.265E+7"}} 18000000136400f104000000000000000000000000483000 18000000136400f104000000000000000000000000483000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-299.phpt0000664000175000017500000000201613210321137022714 0ustar jmikolajmikola--TEST-- Decimal128: [basx232] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000303000 {"d":{"$numberDecimal":"0.00001265"}} 18000000136400f104000000000000000000000000303000 18000000136400f104000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-300.phpt0000664000175000017500000000201413210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [basx242] Numbers with E --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f104000000000000000000000000503000 {"d":{"$numberDecimal":"1.265E+11"}} 18000000136400f104000000000000000000000000503000 18000000136400f104000000000000000000000000503000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-301.phpt0000664000175000017500000000154313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx060] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400185c0ace00000000000000000000383000 {"d":{"$numberDecimal":"345678.5432"}} 18000000136400185c0ace00000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-302.phpt0000664000175000017500000000206713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx059] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400f198670c08000000000000000000363000 {"d":{"$numberDecimal":"345678.54321"}} 18000000136400f198670c08000000000000000000363000 18000000136400f198670c08000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-303.phpt0000664000175000017500000000154713210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx058] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006af90b7c50000000000000000000343000 {"d":{"$numberDecimal":"345678.543210"}} 180000001364006af90b7c50000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-304.phpt0000664000175000017500000000155113210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [basx057] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006a19562522020000000000000000343000 {"d":{"$numberDecimal":"2345678.543210"}} 180000001364006a19562522020000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-305.phpt0000664000175000017500000000155313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [basx056] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006ab9c8733a0b0000000000000000343000 {"d":{"$numberDecimal":"12345678.543210"}} 180000001364006ab9c8733a0b0000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-306.phpt0000664000175000017500000000157213210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx031] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640040af0d8648700000000000000000343000 {"d":{"$numberDecimal":"123456789.000000"}} 1800000013640040af0d8648700000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-307.phpt0000664000175000017500000000157213210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [basx030] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640080910f8648700000000000000000343000 {"d":{"$numberDecimal":"123456789.123456"}} 1800000013640080910f8648700000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-3-valid-308.phpt0000664000175000017500000000157013210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx032] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640080910f8648700000000000000000403000 {"d":{"$numberDecimal":"123456789123456"}} 1800000013640080910f8648700000000000000000403000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-001.phpt0000664000175000017500000000070013210321137023715 0ustar jmikolajmikola--TEST-- Decimal128: [basx564] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-002.phpt0000664000175000017500000000070113210321137023717 0ustar jmikolajmikola--TEST-- Decimal128: [basx565] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-003.phpt0000664000175000017500000000070213210321137023721 0ustar jmikolajmikola--TEST-- Decimal128: [basx566] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-004.phpt0000664000175000017500000000070313210321137023723 0ustar jmikolajmikola--TEST-- Decimal128: [basx567] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-005.phpt0000664000175000017500000000070413210321137023725 0ustar jmikolajmikola--TEST-- Decimal128: [basx568] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-006.phpt0000664000175000017500000000075313210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: [basx590] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-007.phpt0000664000175000017500000000070013210321137023723 0ustar jmikolajmikola--TEST-- Decimal128: [basx562] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-008.phpt0000664000175000017500000000070013210321137023724 0ustar jmikolajmikola--TEST-- Decimal128: [basx563] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-009.phpt0000664000175000017500000000075713210321137023741 0ustar jmikolajmikola--TEST-- Decimal128: [dqbas939] overflow results at different rounding modes (Overflow & Inexact & Rounded) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-010.phpt0000664000175000017500000000073713210321137023727 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr534] negatives (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-011.phpt0000664000175000017500000000073713210321137023730 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr535] negatives (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-012.phpt0000664000175000017500000000073713210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr533] negatives (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-013.phpt0000664000175000017500000000073713210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr532] negatives (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-014.phpt0000664000175000017500000000076013210321137023727 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr432] check rounding modes heeded (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-015.phpt0000664000175000017500000000076013210321137023730 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr433] check rounding modes heeded (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-016.phpt0000664000175000017500000000076013210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr435] check rounding modes heeded (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-017.phpt0000664000175000017500000000076013210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr434] check rounding modes heeded (Rounded & Inexact) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-018.phpt0000664000175000017500000000075613210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: [dqbas938] overflow results at different rounding modes (Overflow & Inexact & Rounded) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-019.phpt0000664000175000017500000000073713210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: Inexact rounding#1 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-parseError-020.phpt0000664000175000017500000000065213210321137023724 0ustar jmikolajmikola--TEST-- Decimal128: Inexact rounding#2 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-001.phpt0000664000175000017500000000154213210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx023] conform to rules and exponent will be in permitted range). --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640001000000000000000000000000003eb000 {"d":{"$numberDecimal":"-0.1"}} 1800000013640001000000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-002.phpt0000664000175000017500000000204213210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: [basx045] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640003000000000000000000000000003a3000 {"d":{"$numberDecimal":"0.003"}} 1800000013640003000000000000000000000000003a3000 1800000013640003000000000000000000000000003a3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-003.phpt0000664000175000017500000000176213210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [basx610] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.0"}} 1800000013640000000000000000000000000000003e3000 1800000013640000000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-004.phpt0000664000175000017500000000176513210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [basx612] Zeros --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000000000000000000000000003eb000 {"d":{"$numberDecimal":"-0.0"}} 1800000013640000000000000000000000000000003eb000 1800000013640000000000000000000000000000003eb000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-005.phpt0000664000175000017500000000204213210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [basx043] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400fc040000000000000000000000003c3000 {"d":{"$numberDecimal":"12.76"}} 18000000136400fc040000000000000000000000003c3000 18000000136400fc040000000000000000000000003c3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-006.phpt0000664000175000017500000000204413210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx055] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000500000000000000000000000000303000 {"d":{"$numberDecimal":"5E-8"}} 180000001364000500000000000000000000000000303000 180000001364000500000000000000000000000000303000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-007.phpt0000664000175000017500000000204313210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx054] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000500000000000000000000000000323000 {"d":{"$numberDecimal":"5E-7"}} 180000001364000500000000000000000000000000323000 180000001364000500000000000000000000000000323000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-008.phpt0000664000175000017500000000153513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [basx052] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000500000000000000000000000000343000 {"d":{"$numberDecimal":"0.000005"}} 180000001364000500000000000000000000000000343000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-009.phpt0000664000175000017500000000205013210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [basx051] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000500000000000000000000000000363000 {"d":{"$numberDecimal":"0.00005"}} 180000001364000500000000000000000000000000363000 180000001364000500000000000000000000000000363000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-010.phpt0000664000175000017500000000153113210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [basx050] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000500000000000000000000000000383000 {"d":{"$numberDecimal":"0.0005"}} 180000001364000500000000000000000000000000383000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-011.phpt0000664000175000017500000000203213210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [basx047] strings without E cannot generate E in result --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640005000000000000000000000000003e3000 {"d":{"$numberDecimal":"0.5"}} 1800000013640005000000000000000000000000003e3000 1800000013640005000000000000000000000000003e3000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-012.phpt0000664000175000017500000000216513210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [dqbsr431] check rounding modes heeded (Rounded) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640099761cc7b548f377dc80a131c836fe2f00 {"d":{"$numberDecimal":"1.111111111111111111111111111112345"}} 1800000013640099761cc7b548f377dc80a131c836fe2f00 1800000013640099761cc7b548f377dc80a131c836fe2f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-4-valid-013.phpt0000664000175000017500000000214313210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: OK2 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31fc2f00 {"d":{"$numberDecimal":"0.1000000000000000000000000000000000"}} 18000000136400000000000a5bc138938d44c64d31fc2f00 18000000136400000000000a5bc138938d44c64d31fc2f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-001.phpt0000664000175000017500000000214213210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [decq035] fold-downs (more below) (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000807f1bcf85b27059c8a43cfe5f00 {"d":{"$numberDecimal":"1.230000000000000000000000000000000E+6144"}} 18000000136400000000807f1bcf85b27059c8a43cfe5f00 18000000136400000000807f1bcf85b27059c8a43cfe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-002.phpt0000664000175000017500000000213713210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq037] fold-downs (more below) (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000000000E+6144"}} 18000000136400000000000a5bc138938d44c64d31fe5f00 18000000136400000000000a5bc138938d44c64d31fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-003.phpt0000664000175000017500000000217013210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq077] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000081efac855b416d2dee04000000 {"d":{"$numberDecimal":"1.00000000000000000000000000000000E-6144"}} 180000001364000000000081efac855b416d2dee04000000 180000001364000000000081efac855b416d2dee04000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-004.phpt0000664000175000017500000000161213210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq078] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000081efac855b416d2dee04000000 {"d":{"$numberDecimal":"1.00000000000000000000000000000000E-6144"}} 180000001364000000000081efac855b416d2dee04000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-005.phpt0000664000175000017500000000207213210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq079] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000000000 {"d":{"$numberDecimal":"1.0E-6175"}} 180000001364000a00000000000000000000000000000000 180000001364000a00000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-006.phpt0000664000175000017500000000151413210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq080] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000000000 {"d":{"$numberDecimal":"1.0E-6175"}} 180000001364000a00000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-007.phpt0000664000175000017500000000206513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq081] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000020000 {"d":{"$numberDecimal":"1E-6175"}} 180000001364000100000000000000000000000000020000 180000001364000100000000000000000000000000020000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-008.phpt0000664000175000017500000000151013210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq082] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000020000 {"d":{"$numberDecimal":"1E-6175"}} 180000001364000100000000000000000000000000020000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-009.phpt0000664000175000017500000000206613210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq083] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000000000 {"d":{"$numberDecimal":"1E-6176"}} 180000001364000100000000000000000000000000000000 180000001364000100000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-010.phpt0000664000175000017500000000151013210321137022671 0ustar jmikolajmikola--TEST-- Decimal128: [decq084] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000000000 {"d":{"$numberDecimal":"1E-6176"}} 180000001364000100000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-011.phpt0000664000175000017500000000210513210321137022673 0ustar jmikolajmikola--TEST-- Decimal128: [decq090] underflows cannot be tested for simple copies, check edge cases (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000000000 {"d":{"$numberDecimal":"1E-6176"}} 180000001364000100000000000000000000000000000000 180000001364000100000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-012.phpt0000664000175000017500000000224713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq100] underflows cannot be tested for simple copies, check edge cases (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff095bc138938d44c64d31000000 {"d":{"$numberDecimal":"9.99999999999999999999999999999999E-6144"}} 18000000136400ffffffff095bc138938d44c64d31000000 18000000136400ffffffff095bc138938d44c64d31000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-013.phpt0000664000175000017500000000214513210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq130] fold-downs (more below) (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000807f1bcf85b27059c8a43cfedf00 {"d":{"$numberDecimal":"-1.230000000000000000000000000000000E+6144"}} 18000000136400000000807f1bcf85b27059c8a43cfedf00 18000000136400000000807f1bcf85b27059c8a43cfedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-014.phpt0000664000175000017500000000214213210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq132] fold-downs (more below) (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31fedf00 {"d":{"$numberDecimal":"-1.000000000000000000000000000000000E+6144"}} 18000000136400000000000a5bc138938d44c64d31fedf00 18000000136400000000000a5bc138938d44c64d31fedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-015.phpt0000664000175000017500000000217313210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq177] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000081efac855b416d2dee04008000 {"d":{"$numberDecimal":"-1.00000000000000000000000000000000E-6144"}} 180000001364000000000081efac855b416d2dee04008000 180000001364000000000081efac855b416d2dee04008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-016.phpt0000664000175000017500000000161413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq178] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000081efac855b416d2dee04008000 {"d":{"$numberDecimal":"-1.00000000000000000000000000000000E-6144"}} 180000001364000000000081efac855b416d2dee04008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-017.phpt0000664000175000017500000000207513210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq179] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000008000 {"d":{"$numberDecimal":"-1.0E-6175"}} 180000001364000a00000000000000000000000000008000 180000001364000a00000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-018.phpt0000664000175000017500000000151613210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq180] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000008000 {"d":{"$numberDecimal":"-1.0E-6175"}} 180000001364000a00000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-019.phpt0000664000175000017500000000207013210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq181] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000028000 {"d":{"$numberDecimal":"-1E-6175"}} 180000001364000100000000000000000000000000028000 180000001364000100000000000000000000000000028000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-020.phpt0000664000175000017500000000151213210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [decq182] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000028000 {"d":{"$numberDecimal":"-1E-6175"}} 180000001364000100000000000000000000000000028000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-021.phpt0000664000175000017500000000207113210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq183] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000008000 {"d":{"$numberDecimal":"-1E-6176"}} 180000001364000100000000000000000000000000008000 180000001364000100000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-022.phpt0000664000175000017500000000151213210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq184] Nmin and below (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000008000 {"d":{"$numberDecimal":"-1E-6176"}} 180000001364000100000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-023.phpt0000664000175000017500000000203513210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq190] underflow edge cases (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000100000000000000000000000000008000 {"d":{"$numberDecimal":"-1E-6176"}} 180000001364000100000000000000000000000000008000 180000001364000100000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-024.phpt0000664000175000017500000000217713210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq200] underflow edge cases (Subnormal) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400ffffffff095bc138938d44c64d31008000 {"d":{"$numberDecimal":"-9.99999999999999999999999999999999E-6144"}} 18000000136400ffffffff095bc138938d44c64d31008000 18000000136400ffffffff095bc138938d44c64d31008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-025.phpt0000664000175000017500000000201113210321137022674 0ustar jmikolajmikola--TEST-- Decimal128: [decq400] zeros (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000000000 {"d":{"$numberDecimal":"0E-6176"}} 180000001364000000000000000000000000000000000000 180000001364000000000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-026.phpt0000664000175000017500000000201113210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq401] zeros (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000000000 {"d":{"$numberDecimal":"0E-6176"}} 180000001364000000000000000000000000000000000000 180000001364000000000000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-027.phpt0000664000175000017500000000202413210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq414] clamped zeros... (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fe5f00 {"d":{"$numberDecimal":"0E+6111"}} 180000001364000000000000000000000000000000fe5f00 180000001364000000000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-028.phpt0000664000175000017500000000202413210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq416] clamped zeros... (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fe5f00 {"d":{"$numberDecimal":"0E+6111"}} 180000001364000000000000000000000000000000fe5f00 180000001364000000000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-029.phpt0000664000175000017500000000202413210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq418] clamped zeros... (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fe5f00 {"d":{"$numberDecimal":"0E+6111"}} 180000001364000000000000000000000000000000fe5f00 180000001364000000000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-030.phpt0000664000175000017500000000202513210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq420] negative zeros (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000008000 {"d":{"$numberDecimal":"-0E-6176"}} 180000001364000000000000000000000000000000008000 180000001364000000000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-031.phpt0000664000175000017500000000202513210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq421] negative zeros (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000008000 {"d":{"$numberDecimal":"-0E-6176"}} 180000001364000000000000000000000000000000008000 180000001364000000000000000000000000000000008000 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-032.phpt0000664000175000017500000000202713210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq434] clamped zeros... (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fedf00 {"d":{"$numberDecimal":"-0E+6111"}} 180000001364000000000000000000000000000000fedf00 180000001364000000000000000000000000000000fedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-033.phpt0000664000175000017500000000202713210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq436] clamped zeros... (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fedf00 {"d":{"$numberDecimal":"-0E+6111"}} 180000001364000000000000000000000000000000fedf00 180000001364000000000000000000000000000000fedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-034.phpt0000664000175000017500000000202713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq438] clamped zeros... (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000000000000000000000000fedf00 {"d":{"$numberDecimal":"-0E+6111"}} 180000001364000000000000000000000000000000fedf00 180000001364000000000000000000000000000000fedf00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-035.phpt0000664000175000017500000000213713210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq601] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000000a5bc138938d44c64d31fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000000000E+6144"}} 18000000136400000000000a5bc138938d44c64d31fe5f00 18000000136400000000000a5bc138938d44c64d31fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-036.phpt0000664000175000017500000000213513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq603] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000000081efac855b416d2dee04fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000000000000E+6143"}} 180000001364000000000081efac855b416d2dee04fe5f00 180000001364000000000081efac855b416d2dee04fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-037.phpt0000664000175000017500000000213313210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq605] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000080264b91c02220be377e00fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000000000000E+6142"}} 1800000013640000000080264b91c02220be377e00fe5f00 1800000013640000000080264b91c02220be377e00fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-038.phpt0000664000175000017500000000213113210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq607] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000000040eaed7446d09c2c9f0c00fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000000E+6141"}} 1800000013640000000040eaed7446d09c2c9f0c00fe5f00 1800000013640000000040eaed7446d09c2c9f0c00fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-039.phpt0000664000175000017500000000212713210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq609] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000a0ca17726dae0f1e430100fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000000000E+6140"}} 18000000136400000000a0ca17726dae0f1e430100fe5f00 18000000136400000000a0ca17726dae0f1e430100fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-040.phpt0000664000175000017500000000212513210321137022677 0ustar jmikolajmikola--TEST-- Decimal128: [decq611] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000106102253e5ece4f200000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000000000E+6139"}} 18000000136400000000106102253e5ece4f200000fe5f00 18000000136400000000106102253e5ece4f200000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-041.phpt0000664000175000017500000000212313210321137022676 0ustar jmikolajmikola--TEST-- Decimal128: [decq613] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000e83c80d09f3c2e3b030000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000000E+6138"}} 18000000136400000000e83c80d09f3c2e3b030000fe5f00 18000000136400000000e83c80d09f3c2e3b030000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-042.phpt0000664000175000017500000000212113210321137022675 0ustar jmikolajmikola--TEST-- Decimal128: [decq615] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000e4d20cc8dcd2b752000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000000E+6137"}} 18000000136400000000e4d20cc8dcd2b752000000fe5f00 18000000136400000000e4d20cc8dcd2b752000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-043.phpt0000664000175000017500000000211713210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq617] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000004a48011416954508000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000000E+6136"}} 180000001364000000004a48011416954508000000fe5f00 180000001364000000004a48011416954508000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-044.phpt0000664000175000017500000000211513210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq619] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000000a1edccce1bc2d300000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000000E+6135"}} 18000000136400000000a1edccce1bc2d300000000fe5f00 18000000136400000000a1edccce1bc2d300000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-045.phpt0000664000175000017500000000211313210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq621] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000080f64ae1c7022d1500000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000000E+6134"}} 18000000136400000080f64ae1c7022d1500000000fe5f00 18000000136400000080f64ae1c7022d1500000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-046.phpt0000664000175000017500000000211113210321137022700 0ustar jmikolajmikola--TEST-- Decimal128: [decq623] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000040b2bac9e0191e0200000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000000E+6133"}} 18000000136400000040b2bac9e0191e0200000000fe5f00 18000000136400000040b2bac9e0191e0200000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-047.phpt0000664000175000017500000000210713210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq625] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000a0dec5adc935360000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000000E+6132"}} 180000001364000000a0dec5adc935360000000000fe5f00 180000001364000000a0dec5adc935360000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-048.phpt0000664000175000017500000000210513210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq627] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000010632d5ec76b050000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000000E+6131"}} 18000000136400000010632d5ec76b050000000000fe5f00 18000000136400000010632d5ec76b050000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-049.phpt0000664000175000017500000000210313210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq629] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000e8890423c78a000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000000E+6130"}} 180000001364000000e8890423c78a000000000000fe5f00 180000001364000000e8890423c78a000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-050.phpt0000664000175000017500000000210113210321137022672 0ustar jmikolajmikola--TEST-- Decimal128: [decq631] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400000064a7b3b6e00d000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000000E+6129"}} 18000000136400000064a7b3b6e00d000000000000fe5f00 18000000136400000064a7b3b6e00d000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-051.phpt0000664000175000017500000000207713210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq633] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000008a5d78456301000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000000E+6128"}} 1800000013640000008a5d78456301000000000000fe5f00 1800000013640000008a5d78456301000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-052.phpt0000664000175000017500000000207513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq635] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000000c16ff2862300000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000000E+6127"}} 180000001364000000c16ff2862300000000000000fe5f00 180000001364000000c16ff2862300000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-053.phpt0000664000175000017500000000207313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq637] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000080c6a47e8d0300000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000000E+6126"}} 180000001364000080c6a47e8d0300000000000000fe5f00 180000001364000080c6a47e8d0300000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-054.phpt0000664000175000017500000000207113210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq639] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000407a10f35a0000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000000E+6125"}} 1800000013640000407a10f35a0000000000000000fe5f00 1800000013640000407a10f35a0000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-055.phpt0000664000175000017500000000206713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq641] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000a0724e18090000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000000E+6124"}} 1800000013640000a0724e18090000000000000000fe5f00 1800000013640000a0724e18090000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-056.phpt0000664000175000017500000000206513210321137022711 0ustar jmikolajmikola--TEST-- Decimal128: [decq643] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000010a5d4e8000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000000E+6123"}} 180000001364000010a5d4e8000000000000000000fe5f00 180000001364000010a5d4e8000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-057.phpt0000664000175000017500000000206313210321137022710 0ustar jmikolajmikola--TEST-- Decimal128: [decq645] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000e8764817000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000000E+6122"}} 1800000013640000e8764817000000000000000000fe5f00 1800000013640000e8764817000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-058.phpt0000664000175000017500000000206113210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq647] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000e40b5402000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000000E+6121"}} 1800000013640000e40b5402000000000000000000fe5f00 1800000013640000e40b5402000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-059.phpt0000664000175000017500000000205713210321137022715 0ustar jmikolajmikola--TEST-- Decimal128: [decq649] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000ca9a3b00000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000000000E+6120"}} 1800000013640000ca9a3b00000000000000000000fe5f00 1800000013640000ca9a3b00000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-060.phpt0000664000175000017500000000205513210321137022703 0ustar jmikolajmikola--TEST-- Decimal128: [decq651] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640000e1f50500000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000000E+6119"}} 1800000013640000e1f50500000000000000000000fe5f00 1800000013640000e1f50500000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-061.phpt0000664000175000017500000000205313210321137022702 0ustar jmikolajmikola--TEST-- Decimal128: [decq653] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364008096980000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000000E+6118"}} 180000001364008096980000000000000000000000fe5f00 180000001364008096980000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-062.phpt0000664000175000017500000000205113210321137022701 0ustar jmikolajmikola--TEST-- Decimal128: [decq655] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1800000013640040420f0000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000000E+6117"}} 1800000013640040420f0000000000000000000000fe5f00 1800000013640040420f0000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-063.phpt0000664000175000017500000000204713210321137022707 0ustar jmikolajmikola--TEST-- Decimal128: [decq657] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400a086010000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00000E+6116"}} 18000000136400a086010000000000000000000000fe5f00 18000000136400a086010000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-064.phpt0000664000175000017500000000204513210321137022706 0ustar jmikolajmikola--TEST-- Decimal128: [decq659] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364001027000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0000E+6115"}} 180000001364001027000000000000000000000000fe5f00 180000001364001027000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-065.phpt0000664000175000017500000000204313210321137022705 0ustar jmikolajmikola--TEST-- Decimal128: [decq661] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 18000000136400e803000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.000E+6114"}} 18000000136400e803000000000000000000000000fe5f00 18000000136400e803000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-066.phpt0000664000175000017500000000204113210321137022704 0ustar jmikolajmikola--TEST-- Decimal128: [decq663] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364006400000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.00E+6113"}} 180000001364006400000000000000000000000000fe5f00 180000001364006400000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-5-valid-067.phpt0000664000175000017500000000203713210321137022712 0ustar jmikolajmikola--TEST-- Decimal128: [decq665] fold-down full sequence (Clamped) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000001364000a00000000000000000000000000fe5f00 {"d":{"$numberDecimal":"1.0E+6112"}} 180000001364000a00000000000000000000000000fe5f00 180000001364000a00000000000000000000000000fe5f00 ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-001.phpt0000664000175000017500000000064613210321137023730 0ustar jmikolajmikola--TEST-- Decimal128: Incomplete Exponent --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-002.phpt0000664000175000017500000000065513210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: Exponent at the beginning --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-003.phpt0000664000175000017500000000064613210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: Just a decimal place --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-004.phpt0000664000175000017500000000064413210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: 2 decimal places --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-005.phpt0000664000175000017500000000064613210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: 2 decimal places --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-006.phpt0000664000175000017500000000064513210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: 2 decimal places --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-007.phpt0000664000175000017500000000064613210321137023736 0ustar jmikolajmikola--TEST-- Decimal128: 2 decimal places --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-008.phpt0000664000175000017500000000064613210321137023737 0ustar jmikolajmikola--TEST-- Decimal128: 2 decimal places --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-009.phpt0000664000175000017500000000065113210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: Decimal with no digits --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-010.phpt0000664000175000017500000000063613210321137023727 0ustar jmikolajmikola--TEST-- Decimal128: 2 signs --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-011.phpt0000664000175000017500000000063613210321137023730 0ustar jmikolajmikola--TEST-- Decimal128: 2 signs --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-012.phpt0000664000175000017500000000064713210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: 2 negative signs --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-013.phpt0000664000175000017500000000064713210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: 2 negative signs --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-014.phpt0000664000175000017500000000065213210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: End in negative sign --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-015.phpt0000664000175000017500000000065213210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: 2 negative signs --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-016.phpt0000664000175000017500000000065213210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: 2 negative signs --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-017.phpt0000664000175000017500000000064113210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: 2 signs --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-018.phpt0000664000175000017500000000063513210321137023736 0ustar jmikolajmikola--TEST-- Decimal128: Empty string --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-019.phpt0000664000175000017500000000066613210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: leading white space positive number --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-020.phpt0000664000175000017500000000066713210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: leading white space negative number --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-021.phpt0000664000175000017500000000064713210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: trailing white space --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-022.phpt0000664000175000017500000000063113210321137023725 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-023.phpt0000664000175000017500000000063713210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-024.phpt0000664000175000017500000000063113210321137023727 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-025.phpt0000664000175000017500000000063213210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-026.phpt0000664000175000017500000000063313210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-027.phpt0000664000175000017500000000063213210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-028.phpt0000664000175000017500000000063313210321137023735 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-029.phpt0000664000175000017500000000063713210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-030.phpt0000664000175000017500000000064313210321137023727 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-6-parseError-031.phpt0000664000175000017500000000064413210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: Invalid --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-001.phpt0000664000175000017500000000070113210321137023721 0ustar jmikolajmikola--TEST-- Decimal128: [basx572] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-002.phpt0000664000175000017500000000075513210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: [basx516] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-003.phpt0000664000175000017500000000076013210321137023730 0ustar jmikolajmikola--TEST-- Decimal128: [basx533] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-004.phpt0000664000175000017500000000076013210321137023731 0ustar jmikolajmikola--TEST-- Decimal128: [basx534] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-005.phpt0000664000175000017500000000076013210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: [basx535] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-006.phpt0000664000175000017500000000070013210321137023725 0ustar jmikolajmikola--TEST-- Decimal128: [basx569] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-007.phpt0000664000175000017500000000070113210321137023727 0ustar jmikolajmikola--TEST-- Decimal128: [basx571] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-008.phpt0000664000175000017500000000070113210321137023730 0ustar jmikolajmikola--TEST-- Decimal128: [basx575] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-009.phpt0000664000175000017500000000075513210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: [basx503] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-010.phpt0000664000175000017500000000075513210321137023732 0ustar jmikolajmikola--TEST-- Decimal128: [basx504] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-011.phpt0000664000175000017500000000075513210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: [basx505] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-012.phpt0000664000175000017500000000075513210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: [basx506] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-013.phpt0000664000175000017500000000075513210321137023735 0ustar jmikolajmikola--TEST-- Decimal128: [basx510] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-014.phpt0000664000175000017500000000075613210321137023737 0ustar jmikolajmikola--TEST-- Decimal128: [basx513] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-015.phpt0000664000175000017500000000075613210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: [basx514] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-016.phpt0000664000175000017500000000075313210321137023736 0ustar jmikolajmikola--TEST-- Decimal128: [basx501] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-017.phpt0000664000175000017500000000075413210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: [basx502] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-018.phpt0000664000175000017500000000075213210321137023737 0ustar jmikolajmikola--TEST-- Decimal128: [basx519] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-019.phpt0000664000175000017500000000075613210321137023744 0ustar jmikolajmikola--TEST-- Decimal128: [basx525] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-020.phpt0000664000175000017500000000075513210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: [basx549] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-021.phpt0000664000175000017500000000074613210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: [basx577] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-022.phpt0000664000175000017500000000074713210321137023736 0ustar jmikolajmikola--TEST-- Decimal128: [basx578] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-023.phpt0000664000175000017500000000074513210321137023735 0ustar jmikolajmikola--TEST-- Decimal128: [basx581] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-024.phpt0000664000175000017500000000074613210321137023737 0ustar jmikolajmikola--TEST-- Decimal128: [basx582] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-025.phpt0000664000175000017500000000074713210321137023741 0ustar jmikolajmikola--TEST-- Decimal128: [basx583] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-026.phpt0000664000175000017500000000074613210321137023741 0ustar jmikolajmikola--TEST-- Decimal128: [basx579] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-027.phpt0000664000175000017500000000074513210321137023741 0ustar jmikolajmikola--TEST-- Decimal128: [basx580] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-028.phpt0000664000175000017500000000074613210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: [basx584] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-029.phpt0000664000175000017500000000074513210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: [basx585] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-030.phpt0000664000175000017500000000074713210321137023735 0ustar jmikolajmikola--TEST-- Decimal128: [basx589] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-031.phpt0000664000175000017500000000074613210321137023735 0ustar jmikolajmikola--TEST-- Decimal128: [basx586] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-032.phpt0000664000175000017500000000074713210321137023737 0ustar jmikolajmikola--TEST-- Decimal128: [basx587] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-033.phpt0000664000175000017500000000075513210321137023737 0ustar jmikolajmikola--TEST-- Decimal128: [basx545] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-034.phpt0000664000175000017500000000070013210321137023726 0ustar jmikolajmikola--TEST-- Decimal128: [basx561] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-035.phpt0000664000175000017500000000070013210321137023727 0ustar jmikolajmikola--TEST-- Decimal128: [basx573] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-036.phpt0000664000175000017500000000075013210321137023735 0ustar jmikolajmikola--TEST-- Decimal128: [basx588] some baddies with dots and Es and dots and specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-037.phpt0000664000175000017500000000075513210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: [basx544] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-038.phpt0000664000175000017500000000075713210321137023746 0ustar jmikolajmikola--TEST-- Decimal128: [basx527] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-039.phpt0000664000175000017500000000075713210321137023747 0ustar jmikolajmikola--TEST-- Decimal128: [basx526] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-040.phpt0000664000175000017500000000075313210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: [basx515] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-041.phpt0000664000175000017500000000070013210321137023724 0ustar jmikolajmikola--TEST-- Decimal128: [basx574] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-042.phpt0000664000175000017500000000076013210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: [basx530] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-043.phpt0000664000175000017500000000075613210321137023741 0ustar jmikolajmikola--TEST-- Decimal128: [basx500] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-044.phpt0000664000175000017500000000075713210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: [basx542] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-045.phpt0000664000175000017500000000076213210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: [basx553] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-046.phpt0000664000175000017500000000076013210321137023737 0ustar jmikolajmikola--TEST-- Decimal128: [basx543] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-047.phpt0000664000175000017500000000076013210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: [basx552] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-048.phpt0000664000175000017500000000075613210321137023746 0ustar jmikolajmikola--TEST-- Decimal128: [basx546] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-049.phpt0000664000175000017500000000075613210321137023747 0ustar jmikolajmikola--TEST-- Decimal128: [basx547] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-050.phpt0000664000175000017500000000075713210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: [basx554] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-051.phpt0000664000175000017500000000075713210321137023741 0ustar jmikolajmikola--TEST-- Decimal128: [basx555] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-052.phpt0000664000175000017500000000075713210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: [basx556] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-053.phpt0000664000175000017500000000075713210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: [basx557] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-054.phpt0000664000175000017500000000075713210321137023744 0ustar jmikolajmikola--TEST-- Decimal128: [basx558] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-055.phpt0000664000175000017500000000075613210321137023744 0ustar jmikolajmikola--TEST-- Decimal128: [basx559] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-056.phpt0000664000175000017500000000075513210321137023744 0ustar jmikolajmikola--TEST-- Decimal128: [basx520] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-057.phpt0000664000175000017500000000075413210321137023744 0ustar jmikolajmikola--TEST-- Decimal128: [basx560] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-058.phpt0000664000175000017500000000075513210321137023746 0ustar jmikolajmikola--TEST-- Decimal128: [basx548] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-059.phpt0000664000175000017500000000075713210321137023751 0ustar jmikolajmikola--TEST-- Decimal128: [basx551] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-060.phpt0000664000175000017500000000076013210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: [basx550] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-061.phpt0000664000175000017500000000076013210321137023734 0ustar jmikolajmikola--TEST-- Decimal128: [basx529] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-062.phpt0000664000175000017500000000076013210321137023735 0ustar jmikolajmikola--TEST-- Decimal128: [basx531] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-063.phpt0000664000175000017500000000076013210321137023736 0ustar jmikolajmikola--TEST-- Decimal128: [basx532] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-064.phpt0000664000175000017500000000075413210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: [basx518] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-065.phpt0000664000175000017500000000076213210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: [basx521] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-066.phpt0000664000175000017500000000070013210321137023733 0ustar jmikolajmikola--TEST-- Decimal128: [basx570] Near-specials (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-067.phpt0000664000175000017500000000075513210321137023746 0ustar jmikolajmikola--TEST-- Decimal128: [basx512] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-068.phpt0000664000175000017500000000075513210321137023747 0ustar jmikolajmikola--TEST-- Decimal128: [basx517] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-069.phpt0000664000175000017500000000075513210321137023750 0ustar jmikolajmikola--TEST-- Decimal128: [basx507] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-070.phpt0000664000175000017500000000075713210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: [basx508] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-071.phpt0000664000175000017500000000075613210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: [basx509] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-072.phpt0000664000175000017500000000076213210321137023740 0ustar jmikolajmikola--TEST-- Decimal128: [basx536] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-073.phpt0000664000175000017500000000076213210321137023741 0ustar jmikolajmikola--TEST-- Decimal128: [basx537] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-074.phpt0000664000175000017500000000076213210321137023742 0ustar jmikolajmikola--TEST-- Decimal128: [basx540] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-075.phpt0000664000175000017500000000076213210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: [basx538] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-076.phpt0000664000175000017500000000076213210321137023744 0ustar jmikolajmikola--TEST-- Decimal128: [basx539] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-077.phpt0000664000175000017500000000076213210321137023745 0ustar jmikolajmikola--TEST-- Decimal128: [basx541] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-078.phpt0000664000175000017500000000076013210321137023744 0ustar jmikolajmikola--TEST-- Decimal128: [basx528] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-079.phpt0000664000175000017500000000077013210321137023746 0ustar jmikolajmikola--TEST-- Decimal128: [basx523] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/decimal128-7-parseError-080.phpt0000664000175000017500000000076613210321137023743 0ustar jmikolajmikola--TEST-- Decimal128: [basx522] The 'baddies' tests from DiagBigDecimal, plus some new ones (Conversion_syntax) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE===mongodb-1.3.4/tests/bson-corpus/document-decodeError-001.phpt0000664000175000017500000000103713210321137023656 0ustar jmikolajmikola--TEST-- Document type (sub-documents): Subdocument length too long: eats outer terminator --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/document-decodeError-002.phpt0000664000175000017500000000102513210321137023654 0ustar jmikolajmikola--TEST-- Document type (sub-documents): Subdocument length too short: leaks terminator --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/document-decodeError-003.phpt0000664000175000017500000000104413210321137023656 0ustar jmikolajmikola--TEST-- Document type (sub-documents): Invalid subdocument: bad string length in field --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/document-valid-001.phpt0000664000175000017500000000131313210321137022515 0ustar jmikolajmikola--TEST-- Document type (sub-documents): Empty subdoc --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0d000000037800050000000000 {"x":{}} 0d000000037800050000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/document-valid-002.phpt0000664000175000017500000000142413210321137022521 0ustar jmikolajmikola--TEST-- Document type (sub-documents): Empty-string key subdoc --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 150000000378000d00000002000200000062000000 {"x":{"":"b"}} 150000000378000d00000002000200000062000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/document-valid-003.phpt0000664000175000017500000000144013210321137022520 0ustar jmikolajmikola--TEST-- Document type (sub-documents): Single-character key subdoc --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 160000000378000e0000000261000200000062000000 {"x":{"a":"b"}} 160000000378000e0000000261000200000062000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/double-decodeError-001.phpt0000664000175000017500000000072313210321137023313 0ustar jmikolajmikola--TEST-- Double type: double truncated --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-001.phpt0000664000175000017500000000201313210321137022147 0ustar jmikolajmikola--TEST-- Double type: +1.0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000000000f03f00 {"d":{"$numberDouble":"1.0"}} {"d":1} 10000000016400000000000000f03f00 {"d":1} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-002.phpt0000664000175000017500000000202013210321137022146 0ustar jmikolajmikola--TEST-- Double type: -1.0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000000000f0bf00 {"d":{"$numberDouble":"-1.0"}} {"d":-1} 10000000016400000000000000f0bf00 {"d":-1} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-003.phpt0000664000175000017500000000212713210321137022157 0ustar jmikolajmikola--TEST-- Double type: +1.0001220703125 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000008000f03f00 {"d":{"$numberDouble":"1.0001220703125"}} {"d":1.0001220703125} 10000000016400000000008000f03f00 {"d":1.0001220703125} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-004.phpt0000664000175000017500000000213413210321137022156 0ustar jmikolajmikola--TEST-- Double type: -1.0001220703125 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000008000f0bf00 {"d":{"$numberDouble":"-1.0001220703125"}} {"d":-1.0001220703125} 10000000016400000000008000f0bf00 {"d":-1.0001220703125} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-005.phpt0000664000175000017500000000227713210321137022167 0ustar jmikolajmikola--TEST-- Double type: 1.23456789012345677E+18 --XFAIL-- Variation in double's string representation (SPEC-850) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 1000000001640081e97df41022b14300 {"d":{"$numberDouble":"1.23456789012345677E+18"}} {"d":1.2345678901235e+18} 1000000001640081e97df41022b14300 {"d":1.2345678901235e+18} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-006.phpt0000664000175000017500000000230513210321137022160 0ustar jmikolajmikola--TEST-- Double type: -1.23456789012345677E+18 --XFAIL-- Variation in double's string representation (SPEC-850) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 1000000001640081e97df41022b1c300 {"d":{"$numberDouble":"-1.23456789012345677E+18"}} {"d":-1.2345678901235e+18} 1000000001640081e97df41022b1c300 {"d":-1.2345678901235e+18} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-007.phpt0000664000175000017500000000201213210321137022154 0ustar jmikolajmikola--TEST-- Double type: 0.0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000000000000000 {"d":{"$numberDouble":"0.0"}} {"d":0} 10000000016400000000000000000000 {"d":0} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-008.phpt0000664000175000017500000000202013210321137022154 0ustar jmikolajmikola--TEST-- Double type: -0.0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000000000008000 {"d":{"$numberDouble":"-0.0"}} {"d":-0} 10000000016400000000000000008000 {"d":-0} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-009.phpt0000664000175000017500000000171613210321137022170 0ustar jmikolajmikola--TEST-- Double type: NaN --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000000000f87f00 {"d":{"$numberDouble":"NaN"}} {"d":{"$numberDouble":"NaN"}} {"d":{"$numberDouble":"NaN"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-010.phpt0000664000175000017500000000173313210321137022157 0ustar jmikolajmikola--TEST-- Double type: NaN with payload --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400120000000000f87f00 {"d":{"$numberDouble":"NaN"}} {"d":{"$numberDouble":"NaN"}} {"d":{"$numberDouble":"NaN"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-011.phpt0000664000175000017500000000214213210321137022153 0ustar jmikolajmikola--TEST-- Double type: Inf --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000000000f07f00 {"d":{"$numberDouble":"Infinity"}} {"d":{"$numberDouble":"Infinity"}} 10000000016400000000000000f07f00 {"d":{"$numberDouble":"Infinity"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/double-valid-012.phpt0000664000175000017500000000215013210321137022153 0ustar jmikolajmikola--TEST-- Double type: -Inf --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000016400000000000000f0ff00 {"d":{"$numberDouble":"-Infinity"}} {"d":{"$numberDouble":"-Infinity"}} 10000000016400000000000000f0ff00 {"d":{"$numberDouble":"-Infinity"}} ===DONE===mongodb-1.3.4/tests/bson-corpus/int32-decodeError-001.phpt0000664000175000017500000000072213210321137022777 0ustar jmikolajmikola--TEST-- Int32 type: Bad int32 field length --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/int32-valid-001.phpt0000664000175000017500000000203413210321137021637 0ustar jmikolajmikola--TEST-- Int32 type: MinValue --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 0c0000001069000000008000 {"i":{"$numberInt":"-2147483648"}} {"i":-2147483648} 0c0000001069000000008000 {"i":-2147483648} ===DONE===mongodb-1.3.4/tests/bson-corpus/int32-valid-002.phpt0000664000175000017500000000202713210321137021642 0ustar jmikolajmikola--TEST-- Int32 type: MaxValue --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 0c000000106900ffffff7f00 {"i":{"$numberInt":"2147483647"}} {"i":2147483647} 0c000000106900ffffff7f00 {"i":2147483647} ===DONE===mongodb-1.3.4/tests/bson-corpus/int32-valid-003.phpt0000664000175000017500000000175113210321137021646 0ustar jmikolajmikola--TEST-- Int32 type: -1 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 0c000000106900ffffffff00 {"i":{"$numberInt":"-1"}} {"i":-1} 0c000000106900ffffffff00 {"i":-1} ===DONE===mongodb-1.3.4/tests/bson-corpus/int32-valid-004.phpt0000664000175000017500000000174313210321137021650 0ustar jmikolajmikola--TEST-- Int32 type: 0 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 0c0000001069000000000000 {"i":{"$numberInt":"0"}} {"i":0} 0c0000001069000000000000 {"i":0} ===DONE===mongodb-1.3.4/tests/bson-corpus/int32-valid-005.phpt0000664000175000017500000000174313210321137021651 0ustar jmikolajmikola--TEST-- Int32 type: 1 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 0c0000001069000100000000 {"i":{"$numberInt":"1"}} {"i":1} 0c0000001069000100000000 {"i":1} ===DONE===mongodb-1.3.4/tests/bson-corpus/int64-decodeError-001.phpt0000664000175000017500000000072713210321137023011 0ustar jmikolajmikola--TEST-- Int64 type: int64 field truncated --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/int64-valid-001.phpt0000664000175000017500000000214413210321137021646 0ustar jmikolajmikola--TEST-- Int64 type: MinValue --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000126100000000000000008000 {"a":{"$numberLong":"-9223372036854775808"}} {"a":-9223372036854775808} 10000000126100000000000000008000 {"a":-9223372036854775808} ===DONE===mongodb-1.3.4/tests/bson-corpus/int64-valid-002.phpt0000664000175000017500000000213713210321137021651 0ustar jmikolajmikola--TEST-- Int64 type: MaxValue --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000126100ffffffffffffff7f00 {"a":{"$numberLong":"9223372036854775807"}} {"a":9223372036854775807} 10000000126100ffffffffffffff7f00 {"a":9223372036854775807} ===DONE===mongodb-1.3.4/tests/bson-corpus/int64-valid-003.phpt0000664000175000017500000000207513210321137021653 0ustar jmikolajmikola--TEST-- Int64 type: -1 --XFAIL-- PHP encodes integers as 32-bit if range allows --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000126100ffffffffffffffff00 {"a":{"$numberLong":"-1"}} {"a":-1} 10000000126100ffffffffffffffff00 {"a":-1} ===DONE===mongodb-1.3.4/tests/bson-corpus/int64-valid-004.phpt0000664000175000017500000000206713210321137021655 0ustar jmikolajmikola--TEST-- Int64 type: 0 --XFAIL-- PHP encodes integers as 32-bit if range allows --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000126100000000000000000000 {"a":{"$numberLong":"0"}} {"a":0} 10000000126100000000000000000000 {"a":0} ===DONE===mongodb-1.3.4/tests/bson-corpus/int64-valid-005.phpt0000664000175000017500000000206713210321137021656 0ustar jmikolajmikola--TEST-- Int64 type: 1 --XFAIL-- PHP encodes integers as 32-bit if range allows --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Relaxed extJSON -> BSON -> Relaxed extJSON echo json_canonicalize(toRelaxedExtendedJSON(fromJSON($relaxedExtJson))), "\n"; ?> ===DONE=== --EXPECT-- 10000000126100010000000000000000 {"a":{"$numberLong":"1"}} {"a":1} 10000000126100010000000000000000 {"a":1} ===DONE===mongodb-1.3.4/tests/bson-corpus/maxkey-valid-001.phpt0000664000175000017500000000125513210321137022202 0ustar jmikolajmikola--TEST-- Maxkey type: Maxkey --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 080000007f610000 {"a":{"$maxKey":1}} 080000007f610000 ===DONE===mongodb-1.3.4/tests/bson-corpus/minkey-valid-001.phpt0000664000175000017500000000125513210321137022200 0ustar jmikolajmikola--TEST-- Minkey type: Minkey --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 08000000ff610000 {"a":{"$minKey":1}} 08000000ff610000 ===DONE===mongodb-1.3.4/tests/bson-corpus/multi-type-valid-001.phpt0000664000175000017500000001310513210321137023012 0ustar jmikolajmikola--TEST-- Multiple types within the same document: All BSON types --XFAIL-- PHP encodes integers as 32-bit if range allows --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- f4010000075f69640057e193d7a9cc81b4027498b502537472696e670007000000737472696e670010496e743332002a00000012496e743634002a0000000000000001446f75626c6500000000000000f0bf0542696e617279001000000003a34c38f7c3abedc8a37814a992ab8db60542696e61727955736572446566696e656400050000008001020304050d436f6465000e00000066756e6374696f6e2829207b7d000f436f64655769746853636f7065001b0000000e00000066756e6374696f6e2829207b7d00050000000003537562646f63756d656e74001200000002666f6f0004000000626172000004417272617900280000001030000100000010310002000000103200030000001033000400000010340005000000001154696d657374616d7000010000002a0000000b5265676578007061747465726e0000094461746574696d6545706f6368000000000000000000094461746574696d65506f73697469766500ffffff7f00000000094461746574696d654e656761746976650000000080ffffffff085472756500010846616c73650000034442526566003d0000000224726566000b000000636f6c6c656374696f6e00072469640057fd71e96e32ab4225b723fb02246462000900000064617461626173650000ff4d696e6b6579007f4d61786b6579000a4e756c6c0000 {"_id":{"$oid":"57e193d7a9cc81b4027498b5"},"String":"string","Int32":{"$numberInt":"42"},"Int64":{"$numberLong":"42"},"Double":{"$numberDouble":"-1.0"},"Binary":{"$binary":{"base64":"o0w498Or7cijeBSpkquNtg==","subType":"03"}},"BinaryUserDefined":{"$binary":{"base64":"AQIDBAU=","subType":"80"}},"Code":{"$code":"function() {}"},"CodeWithScope":{"$code":"function() {}","$scope":{}},"Subdocument":{"foo":"bar"},"Array":[{"$numberInt":"1"},{"$numberInt":"2"},{"$numberInt":"3"},{"$numberInt":"4"},{"$numberInt":"5"}],"Timestamp":{"$timestamp":{"t":42,"i":1}},"Regex":{"$regularExpression":{"pattern":"pattern","options":""}},"DatetimeEpoch":{"$date":{"$numberLong":"0"}},"DatetimePositive":{"$date":{"$numberLong":"2147483647"}},"DatetimeNegative":{"$date":{"$numberLong":"-2147483648"}},"True":true,"False":false,"DBRef":{"$ref":"collection","$id":{"$oid":"57fd71e96e32ab4225b723fb"},"$db":"database"},"Minkey":{"$minKey":1},"Maxkey":{"$maxKey":1},"Null":null} f4010000075f69640057e193d7a9cc81b4027498b502537472696e670007000000737472696e670010496e743332002a00000012496e743634002a0000000000000001446f75626c6500000000000000f0bf0542696e617279001000000003a34c38f7c3abedc8a37814a992ab8db60542696e61727955736572446566696e656400050000008001020304050d436f6465000e00000066756e6374696f6e2829207b7d000f436f64655769746853636f7065001b0000000e00000066756e6374696f6e2829207b7d00050000000003537562646f63756d656e74001200000002666f6f0004000000626172000004417272617900280000001030000100000010310002000000103200030000001033000400000010340005000000001154696d657374616d7000010000002a0000000b5265676578007061747465726e0000094461746574696d6545706f6368000000000000000000094461746574696d65506f73697469766500ffffff7f00000000094461746574696d654e656761746976650000000080ffffffff085472756500010846616c73650000034442526566003d0000000224726566000b000000636f6c6c656374696f6e00072469640057fd71e96e32ab4225b723fb02246462000900000064617461626173650000ff4d696e6b6579007f4d61786b6579000a4e756c6c0000 ===DONE===mongodb-1.3.4/tests/bson-corpus/null-valid-001.phpt0000664000175000017500000000122513210321137021653 0ustar jmikolajmikola--TEST-- Null type: Null --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 080000000a610000 {"a":null} 080000000a610000 ===DONE===mongodb-1.3.4/tests/bson-corpus/oid-decodeError-001.phpt0000664000175000017500000000072713210321137022620 0ustar jmikolajmikola--TEST-- ObjectId: OID truncated --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/oid-valid-001.phpt0000664000175000017500000000144213210321137021455 0ustar jmikolajmikola--TEST-- ObjectId: All zeroes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1400000007610000000000000000000000000000 {"a":{"$oid":"000000000000000000000000"}} 1400000007610000000000000000000000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/oid-valid-002.phpt0000664000175000017500000000144013210321137021454 0ustar jmikolajmikola--TEST-- ObjectId: All ones --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 14000000076100ffffffffffffffffffffffff00 {"a":{"$oid":"ffffffffffffffffffffffff"}} 14000000076100ffffffffffffffffffffffff00 ===DONE===mongodb-1.3.4/tests/bson-corpus/oid-valid-003.phpt0000664000175000017500000000143613210321137021462 0ustar jmikolajmikola--TEST-- ObjectId: Random --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 1400000007610056e1fc72e0c917e9c471416100 {"a":{"$oid":"56e1fc72e0c917e9c4714161"}} 1400000007610056e1fc72e0c917e9c471416100 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-decodeError-001.phpt0000664000175000017500000000075513210321137023160 0ustar jmikolajmikola--TEST-- Regular Expression type: embedded null in pattern --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-decodeError-002.phpt0000664000175000017500000000075513210321137023161 0ustar jmikolajmikola--TEST-- Regular Expression type: embedded null in flags --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-001.phpt0000664000175000017500000000145113210321137022014 0ustar jmikolajmikola--TEST-- Regular Expression type: empty regex with no options --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0a0000000b6100000000 {"a":{"$regularExpression":{"pattern":"","options":""}}} 0a0000000b6100000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-002.phpt0000664000175000017500000000147313210321137022021 0ustar jmikolajmikola--TEST-- Regular Expression type: regex without options --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0d0000000b6100616263000000 {"a":{"$regularExpression":{"pattern":"abc","options":""}}} 0d0000000b6100616263000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-003.phpt0000664000175000017500000000151013210321137022012 0ustar jmikolajmikola--TEST-- Regular Expression type: regex with options --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0f0000000b610061626300696d0000 {"a":{"$regularExpression":{"pattern":"abc","options":"im"}}} 0f0000000b610061626300696d0000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-004.phpt0000664000175000017500000000206113210321137022015 0ustar jmikolajmikola--TEST-- Regular Expression type: regex with options (keys reversed) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0f0000000b610061626300696d0000 {"a":{"$regularExpression":{"pattern":"abc","options":"im"}}} 0f0000000b610061626300696d0000 0f0000000b610061626300696d0000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-005.phpt0000664000175000017500000000152713210321137022024 0ustar jmikolajmikola--TEST-- Regular Expression type: regex with slash --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 110000000b610061622f636400696d0000 {"a":{"$regularExpression":{"pattern":"ab\/cd","options":"im"}}} 110000000b610061622f636400696d0000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-006.phpt0000664000175000017500000000265013210321137022023 0ustar jmikolajmikola--TEST-- Regular Expression type: flags not alphabetized --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate BSON -> Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($degenerateBson))), "\n"; // Degenerate BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($degenerateBson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 100000000b610061626300696d780000 {"a":{"$regularExpression":{"pattern":"abc","options":"imx"}}} 100000000b610061626300696d780000 100000000b610061626300696d780000 {"a":{"$regularExpression":{"pattern":"abc","options":"imx"}}} 100000000b610061626300696d780000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-007.phpt0000664000175000017500000000152513210321137022024 0ustar jmikolajmikola--TEST-- Regular Expression type: Required escapes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 100000000b610061625c226162000000 {"a":{"$regularExpression":{"pattern":"ab\\\"ab","options":""}}} 100000000b610061625c226162000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-008.phpt0000664000175000017500000000166213210321137022027 0ustar jmikolajmikola--TEST-- Regular Expression type: Regular expression as value of $regex query operator --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 180000000b247265676578007061747465726e0069780000 {"$regex":{"$regularExpression":{"pattern":"pattern","options":"ix"}}} 180000000b247265676578007061747465726e0069780000 ===DONE===mongodb-1.3.4/tests/bson-corpus/regex-valid-009.phpt0000664000175000017500000000207113210321137022023 0ustar jmikolajmikola--TEST-- Regular Expression type: Regular expression as value of $regex query operator with $options --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 270000000b247265676578007061747465726e000002246f7074696f6e73000300000069780000 {"$regex":{"$regularExpression":{"pattern":"pattern","options":""}},"$options":"ix"} 270000000b247265676578007061747465726e000002246f7074696f6e73000300000069780000 ===DONE===mongodb-1.3.4/tests/bson-corpus/string-decodeError-001.phpt0000664000175000017500000000074713210321137023355 0ustar jmikolajmikola--TEST-- String: bad string length: 0 (but no 0x00 either) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/string-decodeError-002.phpt0000664000175000017500000000072313210321137023350 0ustar jmikolajmikola--TEST-- String: bad string length: -1 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/string-decodeError-003.phpt0000664000175000017500000000075013210321137023351 0ustar jmikolajmikola--TEST-- String: bad string length: eats terminator --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/string-decodeError-004.phpt0000664000175000017500000000077113210321137023355 0ustar jmikolajmikola--TEST-- String: bad string length: longer than rest of document --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/string-decodeError-005.phpt0000664000175000017500000000074313210321137023355 0ustar jmikolajmikola--TEST-- String: string is not null-terminated --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/string-decodeError-006.phpt0000664000175000017500000000073613210321137023360 0ustar jmikolajmikola--TEST-- String: empty string, but extra null --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/string-decodeError-007.phpt0000664000175000017500000000071713210321137023360 0ustar jmikolajmikola--TEST-- String: invalid UTF-8 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/string-valid-001.phpt0000664000175000017500000000126413210321137022212 0ustar jmikolajmikola--TEST-- String: Empty string --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0d000000026100010000000000 {"a":""} 0d000000026100010000000000 ===DONE===mongodb-1.3.4/tests/bson-corpus/string-valid-002.phpt0000664000175000017500000000130013210321137022202 0ustar jmikolajmikola--TEST-- String: Single character --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0e00000002610002000000620000 {"a":"b"} 0e00000002610002000000620000 ===DONE===mongodb-1.3.4/tests/bson-corpus/string-valid-003.phpt0000664000175000017500000000142713210321137022215 0ustar jmikolajmikola--TEST-- String: Multi-character --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000261000d0000006162616261626162616261620000 {"a":"abababababab"} 190000000261000d0000006162616261626162616261620000 ===DONE===mongodb-1.3.4/tests/bson-corpus/string-valid-004.phpt0000664000175000017500000000152113210321137022211 0ustar jmikolajmikola--TEST-- String: two-byte UTF-8 (é) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000261000d000000c3a9c3a9c3a9c3a9c3a9c3a90000 {"a":"\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9"} 190000000261000d000000c3a9c3a9c3a9c3a9c3a9c3a90000 ===DONE===mongodb-1.3.4/tests/bson-corpus/string-valid-005.phpt0000664000175000017500000000147213210321137022217 0ustar jmikolajmikola--TEST-- String: three-byte UTF-8 (☆) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000261000d000000e29886e29886e29886e298860000 {"a":"\u2606\u2606\u2606\u2606"} 190000000261000d000000e29886e29886e29886e298860000 ===DONE===mongodb-1.3.4/tests/bson-corpus/string-valid-006.phpt0000664000175000017500000000145413210321137022220 0ustar jmikolajmikola--TEST-- String: Embedded nulls --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 190000000261000d0000006162006261620062616261620000 {"a":"ab\u0000bab\u0000babab"} 190000000261000d0000006162006261620062616261620000 ===DONE===mongodb-1.3.4/tests/bson-corpus/string-valid-007.phpt0000664000175000017500000000242213210321137022215 0ustar jmikolajmikola--TEST-- String: Required escapes --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 320000000261002600000061625c220102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f61620000 {"a":"ab\\\"\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001fab"} 320000000261002600000061625c220102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f61620000 ===DONE===mongodb-1.3.4/tests/bson-corpus/timestamp-decodeError-001.phpt0000664000175000017500000000074513210321137024050 0ustar jmikolajmikola--TEST-- Timestamp type: Truncated timestamp field --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/timestamp-valid-001.phpt0000664000175000017500000000145313210321137022707 0ustar jmikolajmikola--TEST-- Timestamp type: Timestamp: (123456789, 42) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 100000001161002a00000015cd5b0700 {"a":{"$timestamp":{"t":123456789,"i":42}}} 100000001161002a00000015cd5b0700 ===DONE===mongodb-1.3.4/tests/bson-corpus/timestamp-valid-002.phpt0000664000175000017500000000200713210321137022704 0ustar jmikolajmikola--TEST-- Timestamp type: Timestamp: (123456789, 42) (keys reversed) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; // Degenerate extJSON -> Canonical BSON echo bin2hex(fromJSON($degenerateExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 100000001161002a00000015cd5b0700 {"a":{"$timestamp":{"t":123456789,"i":42}}} 100000001161002a00000015cd5b0700 100000001161002a00000015cd5b0700 ===DONE===mongodb-1.3.4/tests/bson-corpus/timestamp-valid-003.phpt0000664000175000017500000000154313210321137022711 0ustar jmikolajmikola--TEST-- Timestamp type: Timestamp with high-order bit set on both seconds and increment --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 10000000116100ffffffffffffffff00 {"a":{"$timestamp":{"t":4294967295,"i":4294967295}}} 10000000116100ffffffffffffffff00 ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-001.phpt0000664000175000017500000000105013210321137022635 0ustar jmikolajmikola--TEST-- Top-level document validity: An object size that's too small to even include the object size, but is a well-formed, empty object --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-002.phpt0000664000175000017500000000103613210321137022642 0ustar jmikolajmikola--TEST-- Top-level document validity: An object size that's only enough for the object size, but is a well-formed, empty object --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-003.phpt0000664000175000017500000000077213210321137022651 0ustar jmikolajmikola--TEST-- Top-level document validity: One object, with length shorter than size (missing EOO) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-004.phpt0000664000175000017500000000101513210321137022641 0ustar jmikolajmikola--TEST-- Top-level document validity: One object, sized correctly, with a spot for an EOO, but the EOO is 0x01 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-005.phpt0000664000175000017500000000101513210321137022642 0ustar jmikolajmikola--TEST-- Top-level document validity: One object, sized correctly, with a spot for an EOO, but the EOO is 0xff --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-006.phpt0000664000175000017500000000101513210321137022643 0ustar jmikolajmikola--TEST-- Top-level document validity: One object, sized correctly, with a spot for an EOO, but the EOO is 0x70 --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-007.phpt0000664000175000017500000000077613210321137022661 0ustar jmikolajmikola--TEST-- Top-level document validity: Byte count is zero (with non-zero input length) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-008.phpt0000664000175000017500000000102413210321137022645 0ustar jmikolajmikola--TEST-- Top-level document validity: Stated length exceeds byte count, with truncated document --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-009.phpt0000664000175000017500000000104613210321137022652 0ustar jmikolajmikola--TEST-- Top-level document validity: Stated length less than byte count, with garbage after envelope --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-010.phpt0000664000175000017500000000102413210321137022636 0ustar jmikolajmikola--TEST-- Top-level document validity: Stated length exceeds byte count, with valid envelope --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-011.phpt0000664000175000017500000000102613210321137022641 0ustar jmikolajmikola--TEST-- Top-level document validity: Stated length less than byte count, with valid envelope --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-012.phpt0000664000175000017500000000074413210321137022650 0ustar jmikolajmikola--TEST-- Top-level document validity: Invalid BSON type low range --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-013.phpt0000664000175000017500000000074513210321137022652 0ustar jmikolajmikola--TEST-- Top-level document validity: Invalid BSON type high range --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-decodeError-014.phpt0000664000175000017500000000074313210321137022651 0ustar jmikolajmikola--TEST-- Top-level document validity: Document truncated mid-key --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-001.phpt0000664000175000017500000000100613210321137022525 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $regularExpression (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-002.phpt0000664000175000017500000000075613210321137022541 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $regularExpression (missing options field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-003.phpt0000664000175000017500000000100713210321137022530 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $regularExpression (pattern is number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-004.phpt0000664000175000017500000000101013210321137022523 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $regularExpression (options are number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-005.phpt0000664000175000017500000000075413210321137022542 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $regularExpression (missing pattern field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-006.phpt0000664000175000017500000000070113210321137022533 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $oid (number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-007.phpt0000664000175000017500000000074513210321137022544 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $oid (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-008.phpt0000664000175000017500000000071513210321137022542 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberInt (number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-009.phpt0000664000175000017500000000073313210321137022543 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberInt (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-010.phpt0000664000175000017500000000071713210321137022535 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberLong (number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-011.phpt0000664000175000017500000000073513210321137022536 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberLong (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-012.phpt0000664000175000017500000000072313210321137022534 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberDouble (number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-013.phpt0000664000175000017500000000074113210321137022535 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberDouble (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-014.phpt0000664000175000017500000000072513210321137022540 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberDecimal (number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-015.phpt0000664000175000017500000000074313210321137022541 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $numberDecimal (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-016.phpt0000664000175000017500000000075713210321137022547 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $binary (binary is number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-017.phpt0000664000175000017500000000075313210321137022544 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $binary (type is number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-018.phpt0000664000175000017500000000072313210321137022542 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $binary (missing $type) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-019.phpt0000664000175000017500000000072413210321137022544 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $binary (missing $binary) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-020.phpt0000664000175000017500000000076313210321137022537 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $binary (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-021.phpt0000664000175000017500000000071313210321137022533 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $code (type is number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-022.phpt0000664000175000017500000000071713210321137022540 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $code (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-023.phpt0000664000175000017500000000074413210321137022541 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $code with $scope (scope is number, not doc) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-024.phpt0000664000175000017500000000072313210321137022537 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $timestamp (type is number, not doc) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-025.phpt0000664000175000017500000000076613210321137022547 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $timestamp ('t' type is string, not number) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-026.phpt0000664000175000017500000000076613210321137022550 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $timestamp ('i' type is string, not number) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-027.phpt0000664000175000017500000000102413210321137022535 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $timestamp (extra field at same level as $timestamp) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-028.phpt0000664000175000017500000000102113210321137022533 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $timestamp (extra field at same level as t and i) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-029.phpt0000664000175000017500000000072013210321137022541 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $timestamp (missing t) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-030.phpt0000664000175000017500000000072713210321137022540 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $timestamp (missing i) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-031.phpt0000664000175000017500000000102313210321137022527 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $date (number, not string or hash) --XFAIL-- Legacy extended JSON $date syntax uses numbers (CDRIVER-2223) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-032.phpt0000664000175000017500000000075613210321137022544 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $date (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-033.phpt0000664000175000017500000000073013210321137022535 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad DBRef (ref is number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-034.phpt0000664000175000017500000000074413210321137022543 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad DBRef (db is number, not string) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-035.phpt0000664000175000017500000000071313210321137022540 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $minKey (boolean, not integer) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-036.phpt0000664000175000017500000000070113210321137022536 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $minKey (wrong integer) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-037.phpt0000664000175000017500000000072213210321137022542 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $minKey (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-038.phpt0000664000175000017500000000071313210321137022543 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $maxKey (boolean, not integer) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-039.phpt0000664000175000017500000000070113210321137022541 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $maxKey (wrong integer) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-040.phpt0000664000175000017500000000072213210321137022534 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad $maxKey (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-parseError-041.phpt0000664000175000017500000000105713210321137022537 0ustar jmikolajmikola--TEST-- Top-level document validity: Bad DBpointer (extra field) --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE===mongodb-1.3.4/tests/bson-corpus/top-valid-001.phpt0000664000175000017500000000142513210321137021505 0ustar jmikolajmikola--TEST-- Top-level document validity: Document with keys that start with $ --DESCRIPTION-- Generated by scripts/convert-bson-corpus-tests.php DO NOT EDIT THIS FILE --FILE-- Native -> Canonical BSON echo bin2hex(fromPHP(toPHP($canonicalBson))), "\n"; // Canonical BSON -> Canonical extJSON echo json_canonicalize(toCanonicalExtendedJSON($canonicalBson)), "\n"; // Canonical extJSON -> Canonical BSON echo bin2hex(fromJSON($canonicalExtJson)), "\n"; ?> ===DONE=== --EXPECT-- 0f00000010246b6579002a00000000 {"$key":{"$numberInt":"42"}} 0f00000010246b6579002a00000000 ===DONE===mongodb-1.3.4/tests/bson/bson-binary-001.phpt0000664000175000017500000000650113210321137020520 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary #001 --FILE-- getData() === 'randomBinaryData'); 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=== --EXPECT-- 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" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "00" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "00" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "00" } }" bool(true) Test#1 { "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "01" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "01" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "01" } }" bool(true) Test#2 { "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "02" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "02" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "02" } }" bool(true) Test#3 { "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "03" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "03" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "03" } }" bool(true) Test#4 { "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "04" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "04" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "04" } }" bool(true) Test#5 { "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "05" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "05" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "05" } }" bool(true) Test#6 { "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "80" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "80" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "80" } }" bool(true) Test#7 { "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "85" } } string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "85" } }" string(73) "{ "binary" : { "$binary" : "cmFuZG9tQmluYXJ5RGF0YQ==", "$type" : "85" } }" bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-compare-001.phpt0000664000175000017500000000205313210321137022142 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary comparisons --FILE-- new MongoDB\BSON\Binary('foobar', 1)); // Data length is compared first var_dump(new MongoDB\BSON\Binary('c', 1) < new MongoDB\BSON\Binary('aa', 0)); var_dump(new MongoDB\BSON\Binary('bb', 0) > new MongoDB\BSON\Binary('a', 1)); // Type is compared second var_dump(new MongoDB\BSON\Binary('foobar', 1) < new MongoDB\BSON\Binary('foobar', 2)); var_dump(new MongoDB\BSON\Binary('foobar', 1) > new MongoDB\BSON\Binary('foobar', 0)); // Data is compared last var_dump(new MongoDB\BSON\Binary('foobar', 1) < new MongoDB\BSON\Binary('foobat', 1)); var_dump(new MongoDB\BSON\Binary('foobar', 1) > new MongoDB\BSON\Binary('foobap', 1)); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-compare-002.phpt0000664000175000017500000000220313210321137022140 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary comparisons with null bytes --FILE-- new MongoDB\BSON\Binary("foo\x00bar", 1)); // Data length is compared first var_dump(new MongoDB\BSON\Binary("c\x00", 1) < new MongoDB\BSON\Binary("a\x00a", 0)); var_dump(new MongoDB\BSON\Binary("b\x00b", 0) > new MongoDB\BSON\Binary("a\x00", 1)); // Type is compared second var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) < new MongoDB\BSON\Binary("foo\x00bar", 2)); var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) > new MongoDB\BSON\Binary("foo\x00bar", 0)); // Data is compared last var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) < new MongoDB\BSON\Binary("foo\x00bat", 1)); var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) > new MongoDB\BSON\Binary("foo\x00bap", 1)); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-jsonserialize-001.phpt0000664000175000017500000000047613210321137023404 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary::jsonSerialize() return value --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(2) { ["$binary"]=> string(20) "Z2FyZ2xlYmxhc3Rlcg==" ["$type"]=> string(2) "18" } ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-jsonserialize-002.phpt0000664000175000017500000000120313210321137023372 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary::jsonSerialize() with json_encode() --FILE-- new MongoDB\BSON\Binary('gargleblaster', 24)]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$binary" : "Z2FyZ2xlYmxhc3Rlcg==", "$type" : "18" } } {"foo":{"$binary":"Z2FyZ2xlYmxhc3Rlcg==","$type":"18"}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(13) "gargleblaster" ["type"]=> int(24) } } ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-serialization-001.phpt0000664000175000017500000000373113210321137023375 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary serialization --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(6) "foobar" ["type"]=> int(0) } string(77) "C:19:"MongoDB\BSON\Binary":45:{a:2:{s:4:"data";s:6:"foobar";s:4:"type";i:0;}}" object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(6) "foobar" ["type"]=> int(0) } object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(0) "" ["type"]=> int(0) } string(71) "C:19:"MongoDB\BSON\Binary":39:{a:2:{s:4:"data";s:0:"";s:4:"type";i:0;}}" object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(0) "" ["type"]=> int(0) } object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(4) "%sfoo" ["type"]=> int(0) } string(75) "C:19:"MongoDB\BSON\Binary":43:{a:2:{s:4:"data";s:4:"%sfoo";s:4:"type";i:0;}}" object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(4) "%sfoo" ["type"]=> int(0) } object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(16) "%s" ["type"]=> int(4) } string(88) "C:19:"MongoDB\BSON\Binary":56:{a:2:{s:4:"data";s:16:"%s";s:4:"type";i:4;}}" object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(16) "%s" ["type"]=> int(4) } object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(16) "%s" ["type"]=> int(5) } string(88) "C:19:"MongoDB\BSON\Binary":56:{a:2:{s:4:"data";s:16:"%s";s:4:"type";i:5;}}" object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(16) "%s" ["type"]=> int(5) } ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-serialization_error-001.phpt0000664000175000017500000000220713210321137024603 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary unserialization requires "data" string and "type" integer fields --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Binary initialization requires "data" string and "type" integer fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Binary initialization requires "data" string and "type" integer fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Binary initialization requires "data" string and "type" integer fields ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-serialization_error-002.phpt0000664000175000017500000000145113210321137024604 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary unserialization requires unsigned 8-bit integer for type --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-binary-serialization_error-003.phpt0000664000175000017500000000260613210321137024610 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary unserialization requires 16-byte data length for UUID types --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 15 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 17 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 15 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 17 given ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-set_state-001.phpt0000664000175000017500000000204113210321137022504 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary::__set_state() --FILE-- $data, 'type' => $type, ])); echo "\n\n"; } ?> ===DONE=== --EXPECTF-- MongoDB\BSON\Binary::__set_state(array( %w'data' => 'foobar', %w'type' => 0, )) MongoDB\BSON\Binary::__set_state(array( %w'data' => '', %w'type' => 0, )) MongoDB\BSON\Binary::__set_state(array( %w'data' => '' . "\0" . 'foo', %w'type' => 0, )) MongoDB\BSON\Binary::__set_state(array( %w'data' => '>Egè›Ó¤VBfUD' . "\0" . '' . "\0" . '', %w'type' => 4, )) MongoDB\BSON\Binary::__set_state(array( %w'data' => '8Xö"0¬<‘_0 fCÆ?', %w'type' => 5, )) ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-set_state_error-001.phpt0000664000175000017500000000210113210321137023712 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary::__set_state() requires "data" string and "type" integer fields --FILE-- 'foobar']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Binary::__set_state(['type' => 0]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Binary::__set_state(['data' => 0, 'type' => 'foobar']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Binary initialization requires "data" string and "type" integer fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Binary initialization requires "data" string and "type" integer fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Binary initialization requires "data" string and "type" integer fields ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-set_state_error-002.phpt0000664000175000017500000000136613210321137023727 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary::__set_state() requires unsigned 8-bit integer for type --FILE-- 'foobar', 'type' => -1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Binary::__set_state(['data' => 'foobar', 'type' => 256]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-binary-set_state_error-003.phpt0000664000175000017500000000263113210321137023724 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary::__set_state() requires 16-byte data length for UUID types --FILE-- '0123456789abcde', 'type' => MongoDB\BSON\Binary::TYPE_OLD_UUID]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Binary::__set_state(['data' => '0123456789abcdefg', 'type' => MongoDB\BSON\Binary::TYPE_OLD_UUID]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Binary::__set_state(['data' => '0123456789abcde', 'type' => MongoDB\BSON\Binary::TYPE_UUID]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Binary::__set_state(['data' => '0123456789abcdefg', 'type' => MongoDB\BSON\Binary::TYPE_UUID]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 15 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 17 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 15 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 17 given ===DONE=== mongodb-1.3.4/tests/bson/bson-binary-tostring-001.phpt0000664000175000017500000000036113210321137022365 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary::__toString() --FILE-- ===DONE=== --EXPECT-- string(6) "foobar" ===DONE=== mongodb-1.3.4/tests/bson/bson-binary_error-001.phpt0000664000175000017500000000143513210321137021732 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary #001 error --SKIPIF-- --FILE-- getData(2); $binary->getType(2); throws(function() { new MongoDB\BSON\Binary("random binary data without type"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); ?> ===DONE=== --EXPECTF-- Warning: MongoDB\BSON\Binary::getData() expects exactly 0 parameters, 1 given in %s on line %d Warning: MongoDB\BSON\Binary::getType() expects exactly 0 parameters, 1 given in %s on line %d OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.3.4/tests/bson/bson-binary_error-002.phpt0000664000175000017500000000037713210321137021737 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyBinary may not inherit from final class (MongoDB\BSON\Binary) in %s on line %d mongodb-1.3.4/tests/bson/bson-binary_error-003.phpt0000664000175000017500000000125713210321137021736 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary constructor requires unsigned 8-bit integer for type --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-binary_error-004.phpt0000664000175000017500000000243213210321137021733 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Binary constructor requires 16-byte data length for UUID types --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 15 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 17 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 15 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected UUID length to be 16 bytes, 17 given ===DONE=== mongodb-1.3.4/tests/bson/bson-binaryinterface-001.phpt0000664000175000017500000000044613210321137022403 0ustar jmikolajmikola--TEST-- MongoDB\BSON\BinaryInterface is implemented by MongoDB\BSON\Binary --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-001.phpt0000664000175000017500000000123013210321137021057 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- 1234.5678 -1234.5678 1.234E+8 1.234E+8 1.23456E-75 -234.567 2.345E+9 0.002345 1234.5678 -1234.5678 -234.567 123400000 1.23456E-75 ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-002.phpt0000664000175000017500000000065613210321137021073 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 NaN values --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- NaN NaN NaN NaN NaN NaN ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-003.phpt0000664000175000017500000000106013210321137021062 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 Infinity values --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- Infinity Infinity Infinity Infinity Infinity Infinity Infinity Infinity ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-004.phpt0000664000175000017500000000113413210321137021065 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 debug handler --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(9) "1234.5678" } object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(3) "NaN" } object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(8) "Infinity" } ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-jsonserialize-001.phpt0000664000175000017500000000064313210321137023745 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128::jsonSerialize() return value --SKIPIF-- --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(1) { ["$numberDecimal"]=> string(14) "12389719287312" } ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-jsonserialize-002.phpt0000664000175000017500000000132213210321137023741 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128::jsonSerialize() with json_encode() --SKIPIF-- --FILE-- new MongoDB\BSON\Decimal128('12389719287312')]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$numberDecimal" : "12389719287312" } } {"foo":{"$numberDecimal":"12389719287312"}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(14) "12389719287312" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-serialization-001.phpt0000664000175000017500000000326413210321137023743 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 serialization --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(9) "1234.5678" } string(68) "C:23:"MongoDB\BSON\Decimal128":32:{a:1:{s:3:"dec";s:9:"1234.5678";}}" object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(9) "1234.5678" } object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(10) "-1234.5678" } string(70) "C:23:"MongoDB\BSON\Decimal128":34:{a:1:{s:3:"dec";s:10:"-1234.5678";}}" object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(10) "-1234.5678" } object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(11) "1.23456E-75" } string(71) "C:23:"MongoDB\BSON\Decimal128":35:{a:1:{s:3:"dec";s:11:"1.23456E-75";}}" object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(11) "1.23456E-75" } object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(8) "Infinity" } string(67) "C:23:"MongoDB\BSON\Decimal128":31:{a:1:{s:3:"dec";s:8:"Infinity";}}" object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(8) "Infinity" } object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(3) "NaN" } string(62) "C:23:"MongoDB\BSON\Decimal128":26:{a:1:{s:3:"dec";s:3:"NaN";}}" object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(3) "NaN" } ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-serialization_error-001.phpt0000664000175000017500000000114113210321137025144 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 unserialization requires "dec" string field --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Decimal128 initialization requires "dec" string field ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-serialization_error-002.phpt0000664000175000017500000000112313210321137025145 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 unserialization requires valid decimal string --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing Decimal128 string: INVALID ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-set_state-001.phpt0000664000175000017500000000160213210321137023053 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128::__set_state() --SKIPIF-- --FILE-- $value, ])); echo "\n\n"; } ?> ===DONE=== --EXPECTF-- MongoDB\BSON\Decimal128::__set_state(array( %w'dec' => '1234.5678', )) MongoDB\BSON\Decimal128::__set_state(array( %w'dec' => '-1234.5678', )) MongoDB\BSON\Decimal128::__set_state(array( %w'dec' => 'Infinity', )) MongoDB\BSON\Decimal128::__set_state(array( %w'dec' => 'Infinity', )) MongoDB\BSON\Decimal128::__set_state(array( %w'dec' => 'NaN', )) MongoDB\BSON\Decimal128::__set_state(array( %w'dec' => 'NaN', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-set_state_error-001.phpt0000664000175000017500000000111313210321137024261 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128::__set_state() requires "dec" string field --SKIPIF-- --FILE-- 0]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Decimal128 initialization requires "dec" string field ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128-set_state_error-002.phpt0000664000175000017500000000107313210321137024267 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128::__set_state() requires valid decimal string --SKIPIF-- --FILE-- 'INVALID']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing Decimal128 string: INVALID ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128_error-001.phpt0000664000175000017500000000123713210321137022277 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 requires valid decimal string --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Decimal128::__construct() expects parameter 1 to be string, array given ===DONE=== mongodb-1.3.4/tests/bson/bson-decimal128_error-002.phpt0000664000175000017500000000042313210321137022274 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128 cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyDecimal128 may not inherit from final class (MongoDB\BSON\Decimal128) in %s on line %d mongodb-1.3.4/tests/bson/bson-decimal128interface-001.phpt0000664000175000017500000000043313210321137022744 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Decimal128Interface is implemented by MongoDB\BSON\Decimal128 --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-decode-001.phpt0000664000175000017500000000372513210321137020464 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding data into BSON representation, and BSON into Extended JSON --FILE-- "world"), array((object)array("hello" => "world")), array(null), array(123), array(4.125), 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.125 } 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.3.4/tests/bson/bson-decode-002.phpt0000664000175000017500000000516313210321137020463 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding object/arrays data into user specificied classes --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.3.4/tests/bson/bson-encode-001.phpt0000664000175000017500000001675613210321137020506 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding data into BSON representation, and BSON into Extended JSON --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.125), 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.125 } 0 : 10 00 00 00 01 30 00 00 00 00 00 00 80 10 40 00 [.....0........@.] 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.3.4/tests/bson/bson-encode-002.phpt0000664000175000017500000000734313210321137020477 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding objects into BSON representation --FILE-- "class", "data"); } public function bsonUnserialize(array $data) { echo __METHOD__, "() was called with data:\n"; var_dump($data); } } class NumericArray implements MongoDB\BSON\Serializable, MongoDB\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.3.4/tests/bson/bson-encode-003.phpt0000664000175000017500000001032013210321137020465 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding objects into BSON representation --SKIPIF-- --FILE-- "class", "data" ); } function bsonUnserialize(array $data) { $this->props = $data; } } class MyClass2 implements MongoDB\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" : { "$binary" : "TXlDbGFzcw==", "$type" : "80" }, "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(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } ["random"]=> string(5) "class" [0]=> string(4) "data" } } } Test#1 { "stuff" : { "__pclass" : { "$binary" : "TXlDbGFzczI=", "$type" : "80" }, "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(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(8) "MyClass2" ["type"]=> int(128) } [0]=> int(1) [1]=> int(2) [2]=> int(3) } } } Test#2 { "stuff" : [ { "__pclass" : { "$binary" : "TXlDbGFzcw==", "$type" : "80" }, "random" : "class", "0" : "data" }, { "__pclass" : { "$binary" : "TXlDbGFzczI=", "$type" : "80" }, "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(MongoDB\BSON\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(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(8) "MyClass2" ["type"]=> int(128) } [0]=> int(1) [1]=> int(2) [2]=> int(3) } } } } ===DONE=== mongodb-1.3.4/tests/bson/bson-encode-004.phpt0000664000175000017500000001054513210321137020477 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" : { "$binary" : "UGVyc29u", "$type" : "80" }, "name" : "Hannes", "age" : 42, "addresses" : [ { "__pclass" : { "$binary" : "QWRkcmVzcw==", "$type" : "80" }, "zip" : 94086, "country" : "USA" }, { "__pclass" : { "$binary" : "QWRkcmVzcw==", "$type" : "80" }, "zip" : 200, "country" : "Iceland" } ], "friends" : [ { "__pclass" : { "$binary" : "UGVyc29u", "$type" : "80" }, "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) { [%r(0|"0")%r]=> 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.3.4/tests/bson/bson-encode-005.phpt0000664000175000017500000000133713210321137020477 0ustar jmikolajmikola--TEST-- BSON encoding: Object Document Mapper --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.3.4/tests/bson/bson-fromJSON-001.phpt0000664000175000017500000000202213210321137020663 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromJSON(): Decoding JSON --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.3.4/tests/bson/bson-fromJSON-002.phpt0000664000175000017500000000435013210321137020672 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromJSON(): Decoding extended JSON types --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.3.4/tests/bson/bson-fromJSON_error-001.phpt0000664000175000017500000000050113210321137022074 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromJSON(): invalid JSON --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP-001.phpt0000664000175000017500000000254713210321137020555 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromPHP(): bsonSerialize() allows array and stdClass --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=== --EXPECT-- 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.3.4/tests/bson/bson-fromPHP-002.phpt0000664000175000017500000000076313210321137020554 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromPHP(): Encoding non-Persistable objects as a document --INI-- date.timezone=America/Los_Angeles --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.3.4/tests/bson/bson-fromPHP-003.phpt0000664000175000017500000000234013210321137020546 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromPHP(): Encoding non-Persistable objects as a document field value --INI-- date.timezone=America/Los_Angeles --FILE-- new MongoDB\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.3.4/tests/bson/bson-fromPHP-005.phpt0000664000175000017500000000105213210321137020547 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): PHP document with public property whose name is an empty string --FILE-- 1], (object) ['' => 1], ]; foreach ($tests as $document) { $s = fromPHP($document); echo "Test ", toJSON($s), "\n"; hex_dump($s); } ?> ===DONE=== --EXPECT-- Test { "" : 1 } 0 : 0b 00 00 00 10 00 01 00 00 00 00 [...........] Test { "" : 1 } 0 : 0b 00 00 00 10 00 01 00 00 00 00 [...........] ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP-006.phpt0000664000175000017500000000153613210321137020557 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): PHP documents with null bytes in field name --FILE-- 1])); echo "\nTesting object with multiple null bytes in field name\n"; hex_dump(fromPHP((object) ["\0\0\0" => 1])); ?> ===DONE=== --EXPECT-- Testing object with one leading null byte in field name 0 : 05 00 00 00 00 [.....] Testing object with multiple null bytes in field name 0 : 05 00 00 00 00 [.....] ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP_error-001.phpt0000664000175000017500000000366213210321137021765 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromPHP(): bsonSerialize() must return an array or stdClass --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.3.4/tests/bson/bson-fromPHP_error-002.phpt0000664000175000017500000000134213210321137021757 0ustar jmikolajmikola--TEST--o MongoDB\BSON\fromPHP(): Encoding unknown Type objects as a document field value --FILE-- new UnknownType()), ); foreach ($tests as $document) { echo throws(function() use ($document) { fromPHP($document); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; } ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Unexpected MongoDB\BSON\Type instance: UnknownType OK: Got MongoDB\Driver\Exception\UnexpectedValueException Unexpected MongoDB\BSON\Type instance: UnknownType ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP_error-003.phpt0000664000175000017500000000425013210321137021761 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromPHP(): Encoding non-Serializable Type objects as a root element --INI-- date.timezone=America/Los_Angeles --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance UnknownType cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\Binary cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\Javascript cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\MinKey cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\MaxKey cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\ObjectId cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\Regex cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\Timestamp cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException MongoDB\BSON\Type instance MongoDB\BSON\UTCDateTime cannot be serialized as a root element ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP_error-004.phpt0000664000175000017500000000253113210321137021762 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): PHP documents with circular references --FILE-- 1, 'y' => []]; $document['y'][] = &$document['y']; fromPHP($document); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting associative array with circular reference\n"; echo throws(function() { $document = ['x' => 1, 'y' => []]; $document['y']['z'] = &$document['y']; fromPHP($document); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting object with circular reference\n"; echo throws(function() { $document = (object) ['x' => 1, 'y' => (object) []]; $document->y->z = &$document->y; fromPHP($document); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- Testing packed array with circular reference OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected recursion for fieldname "0" Testing associative array with circular reference OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected recursion for fieldname "z" Testing object with circular reference OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected recursion for fieldname "z" ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP_error-005.phpt0000664000175000017500000000240213210321137021760 0ustar jmikolajmikola--TEST-- MongoDB\BSON\fromPHP(): Serializable with circular references --FILE-- $this]; } } echo "\nTesting Serializable with direct circular reference\n"; echo throws(function() { fromPHP(new MyRecursiveSerializable); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting Serializable with indirect circular reference\n"; echo throws(function() { fromPHP(new MyIndirectlyRecursiveSerializable); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- Testing Serializable with direct circular reference OK: Got MongoDB\Driver\Exception\UnexpectedValueException Expected MyRecursiveSerializable::bsonSerialize() to return an array or stdClass, MyRecursiveSerializable given Testing Serializable with indirect circular reference OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected recursion for fieldname "x" ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP_error-006.phpt0000664000175000017500000000317413210321137021770 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): PHP documents with null bytes in field name --FILE-- 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting array with one trailing null byte in field name\n"; echo throws(function() { fromPHP(["a\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting array with multiple null bytes in field name\n"; echo throws(function() { fromPHP(["\0\0\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting object with one trailing null byte in field name\n"; echo throws(function() { fromPHP((object) ["a\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- Testing array with one leading null byte in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". Testing array with one trailing null byte in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "a". Testing array with multiple null bytes in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". Testing object with one trailing null byte in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "a". ===DONE=== mongodb-1.3.4/tests/bson/bson-fromPHP_error-007.phpt0000664000175000017500000000611013210321137021762 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): Serializable returns document with null bytes in field name --FILE-- data = $data; } public function bsonSerialize() { return $this->data; } } echo "\nTesting array with one leading null byte in field name\n"; echo throws(function() { fromPHP(new MySerializable(["\0" => 1])); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting array with one trailing null byte in field name\n"; echo throws(function() { fromPHP(new MySerializable(["a\0" => 1])); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting array with multiple null bytes in field name\n"; echo throws(function() { fromPHP(new MySerializable(["\0\0\0" => 1])); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; /* Per PHPC-884, field names with a leading null byte are ignored when encoding * a document from an object's property hash table, since PHP uses leading bytes * to denote protected and private properties. However, in this case the object * was returned from Serializable::bsonSerialize() and we skip the check for * protected and private properties. */ echo "\nTesting object with one leading null byte in field name\n"; echo throws(function() { fromPHP(new MySerializable((object) ["\0" => 1])); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting object with one trailing null byte in field name\n"; echo throws(function() { fromPHP(new MySerializable((object) ["a\0" => 1])); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; echo "\nTesting object with multiple null bytes in field name\n"; echo throws(function() { fromPHP(new MySerializable((object) ["\0\0\0" => 1])); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- Testing array with one leading null byte in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". Testing array with one trailing null byte in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "a". Testing array with multiple null bytes in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". Testing object with one leading null byte in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". Testing object with one trailing null byte in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "a". Testing object with multiple null bytes in field name OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". ===DONE=== mongodb-1.3.4/tests/bson/bson-generate-document-id.phpt0000664000175000017500000000273613210321137022744 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.3.4/tests/bson/bson-javascript-001.phpt0000664000175000017500000000136713210321137021407 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript #001 --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 MongoDB\BSON\Javascript); var_dump($testagain->js instanceof MongoDB\BSON\Javascript); } ?> ===DONE=== --EXPECT-- Test#0 bool(true) bool(true) Test#1 bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-002.phpt0000664000175000017500000000223613210321137021404 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript debug handler --FILE-- 42), ), array( 'function foo() { return id; }', array('id' => new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603')), ), ); foreach ($tests as $test) { list($code, $scope) = $test; $js = new MongoDB\BSON\Javascript($code, $scope); var_dump($js); } ?> ===DONE=== --EXPECTF-- object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> object(stdClass)#%d (%d) { } } object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(30) "function foo() { return foo; }" ["scope"]=> object(stdClass)#%d (%d) { ["foo"]=> int(42) } } object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> 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.3.4/tests/bson/bson-javascript-compare-001.phpt0000664000175000017500000000103513210321137023023 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript comparisons (without scope) --FILE-- new MongoDB\BSON\Javascript('function() { return 0; }')); ?> ===DONE=== --EXPECT-- bool(true) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-compare-002.phpt0000664000175000017500000000122313210321137023023 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript comparisons (with scope) --FILE-- 1]) == new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 1])); var_dump(new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 1]) == new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 0])); var_dump(new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 1]) == new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 2])); ?> ===DONE=== --EXPECT-- bool(true) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-getCode-001.phpt0000664000175000017500000000131213210321137022745 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::getCode() --FILE-- 42]], ['function foo() { return id; }', ['id' => new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603')]], ]; foreach ($tests as $test) { list($code, $scope) = $test; $js = new MongoDB\BSON\Javascript($code, $scope); var_dump($js->getCode()); } ?> ===DONE=== --EXPECT-- string(33) "function foo(bar) { return bar; }" string(33) "function foo(bar) { return bar; }" string(30) "function foo() { return foo; }" string(29) "function foo() { return id; }" ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-getScope-001.phpt0000664000175000017500000000137313210321137023153 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::getScope() --FILE-- 42]], ['function foo() { return id; }', ['id' => new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603')]], ]; foreach ($tests as $test) { list($code, $scope) = $test; $js = new MongoDB\BSON\Javascript($code, $scope); var_dump($js->getScope()); } ?> ===DONE=== --EXPECTF-- NULL object(stdClass)#%d (%d) { } object(stdClass)#%d (%d) { ["foo"]=> int(42) } object(stdClass)#%d (%d) { ["id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "53e2a1c40640fd72175d4603" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-jsonserialize-001.phpt0000664000175000017500000000051213210321137024255 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::jsonSerialize() return value (without scope) --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(1) { ["$code"]=> string(33) "function foo(bar) { return bar; }" } ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-jsonserialize-002.phpt0000664000175000017500000000064113210321137024261 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::jsonSerialize() return value (with scope) --FILE-- 42]); var_dump($js->jsonSerialize()); ?> ===DONE=== --EXPECTF-- array(2) { ["$code"]=> string(33) "function foo(bar) { return bar; }" ["$scope"]=> object(stdClass)#%d (%d) { ["foo"]=> int(42) } } ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-jsonserialize-003.phpt0000664000175000017500000000127213210321137024263 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::jsonSerialize() with json_encode() (without scope) --FILE-- new MongoDB\BSON\Javascript('function foo(bar) { return bar; }')]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$code" : "function foo(bar) { return bar; }" } } {"foo":{"$code":"function foo(bar) { return bar; }"}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> NULL } } ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-jsonserialize-004.phpt0000664000175000017500000000145713210321137024271 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::jsonSerialize() with json_encode() (with scope) --FILE-- new MongoDB\BSON\Javascript('function foo(bar) { return bar; }', ['foo' => 42])]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$code" : "function foo(bar) { return bar; }", "$scope" : { "foo" : 42 } } } {"foo":{"$code":"function foo(bar) { return bar; }","$scope":{"foo":42}}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> object(stdClass)#%d (%d) { ["foo"]=> int(42) } } } ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-serialization-001.phpt0000664000175000017500000000521613210321137024257 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript serialization --FILE-- 42]], ['function foo() { return id; }', ['id' => new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603')]], ]; foreach ($tests as $test) { list($code, $scope) = $test; var_dump($js = new MongoDB\BSON\Javascript($code, $scope)); var_dump($s = serialize($js)); var_dump(unserialize($s)); echo "\n"; } ?> ===DONE=== --EXPECTF-- object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> NULL } string(108) "C:23:"MongoDB\BSON\Javascript":72:{a:2:{s:4:"code";s:33:"function foo(bar) { return bar; }";s:5:"scope";N;}}" object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> NULL } object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> object(stdClass)#%d (%d) { } } string(125) "C:23:"MongoDB\BSON\Javascript":89:{a:2:{s:4:"code";s:33:"function foo(bar) { return bar; }";s:5:"scope";O:8:"stdClass":0:{}}}" object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> object(stdClass)#%d (%d) { } } object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(30) "function foo() { return foo; }" ["scope"]=> object(stdClass)#%d (%d) { ["foo"]=> int(42) } } string(138) "C:23:"MongoDB\BSON\Javascript":101:{a:2:{s:4:"code";s:30:"function foo() { return foo; }";s:5:"scope";O:8:"stdClass":1:{s:3:"foo";i:42;}}}" object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(30) "function foo() { return foo; }" ["scope"]=> object(stdClass)#%d (%d) { ["foo"]=> int(42) } } object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(29) "function foo() { return id; }" ["scope"]=> object(stdClass)#%d (%d) { ["id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "53e2a1c40640fd72175d4603" } } } string(213) "C:23:"MongoDB\BSON\Javascript":176:{a:2:{s:4:"code";s:29:"function foo() { return id; }";s:5:"scope";O:8:"stdClass":1:{s:2:"id";C:21:"MongoDB\BSON\ObjectId":48:{a:1:{s:3:"oid";s:24:"53e2a1c40640fd72175d4603";}}}}}" object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> 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.3.4/tests/bson/bson-javascript-serialization_error-001.phpt0000664000175000017500000000075013210321137025466 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript unserialization requires "code" string field --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Javascript initialization requires "code" string field ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-serialization_error-002.phpt0000664000175000017500000000102613210321137025464 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript unserialization expects optional scope to be array or object --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected scope to be array or object, string given ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-serialization_error-003.phpt0000664000175000017500000000077513210321137025477 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript unserialization does not allow code to contain null bytes --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Code cannot contain null bytes ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-set_state-001.phpt0000664000175000017500000000277713210321137023406 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::__set_state() --FILE-- 42]], ['function foo() { return id; }', ['id' => new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603')]], ]; foreach ($tests as $test) { list($code, $scope) = $test; var_export(MongoDB\BSON\Javascript::__set_state([ 'code' => $code, 'scope' => $scope, ])); echo "\n\n"; } // Test with missing scope field var_export(MongoDB\BSON\Javascript::__set_state([ 'code' => 'function foo(bar) { return bar; }', ])); echo "\n\n"; ?> ===DONE=== --EXPECTF-- MongoDB\BSON\Javascript::__set_state(array( %w'code' => 'function foo(bar) { return bar; }', %w'scope' => NULL, )) MongoDB\BSON\Javascript::__set_state(array( %w'code' => 'function foo(bar) { return bar; }', %w'scope' => stdClass::__set_state(array( )), )) MongoDB\BSON\Javascript::__set_state(array( %w'code' => 'function foo() { return foo; }', %w'scope' => stdClass::__set_state(array( %w'foo' => 42, )), )) MongoDB\BSON\Javascript::__set_state(array( %w'code' => 'function foo() { return id; }', %w'scope' => stdClass::__set_state(array( %w'id' => MongoDB\BSON\ObjectId::__set_state(array( %w'oid' => '53e2a1c40640fd72175d4603', )), )), )) MongoDB\BSON\Javascript::__set_state(array( %w'code' => 'function foo(bar) { return bar; }', %w'scope' => NULL, )) ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-set_state_error-001.phpt0000664000175000017500000000072213210321137024603 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::__set_state() requires "code" string field --FILE-- 0]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Javascript initialization requires "code" string field ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-set_state_error-002.phpt0000664000175000017500000000077213210321137024611 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::__set_state() expects optional scope to be array or object --FILE-- 'function foo() {}', 'scope' => 'INVALID']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected scope to be array or object, string given ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-set_state_error-003.phpt0000664000175000017500000000073213210321137024606 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::__set_state() does not allow code to contain null bytes --FILE-- "function foo() { return '\0'; }"]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Code cannot contain null bytes ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript-tostring-001.phpt0000664000175000017500000000062313210321137023250 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::__toString() --FILE-- 1]); var_dump((string) $js); ?> ===DONE=== --EXPECT-- string(28) "function foo() { return 1; }" string(30) "function foo() { return bar; }" ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript_error-001.phpt0000664000175000017500000000067213210321137022616 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript #001 error --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.3.4/tests/bson/bson-javascript_error-002.phpt0000664000175000017500000000042313210321137022611 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyJavascript may not inherit from final class (MongoDB\BSON\Javascript) in %s on line %d mongodb-1.3.4/tests/bson/bson-javascript_error-003.phpt0000664000175000017500000000070513210321137022615 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Javascript::__construct() does not allow code to contain null bytes --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Code cannot contain null bytes ===DONE=== mongodb-1.3.4/tests/bson/bson-javascriptinterface-001.phpt0000664000175000017500000000050413210321137023260 0ustar jmikolajmikola--TEST-- MongoDB\BSON\JavascriptInterface is implemented by MongoDB\BSON\Javascript --FILE-- 1]); var_dump($javascript instanceof MongoDB\BSON\JavascriptInterface); ?> ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-maxkey-001.phpt0000664000175000017500000000122013210321137020523 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKey #001 --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=== --EXPECT-- Test#0 { "max" : { "$maxKey" : 1 } } string(29) "{ "max" : { "$maxKey" : 1 } }" string(29) "{ "max" : { "$maxKey" : 1 } }" bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-maxkey-compare-001.phpt0000664000175000017500000000051313210321137022153 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKey comparisons --FILE-- new MongoDB\BSON\MaxKey); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) ===DONE=== mongodb-1.3.4/tests/bson/bson-maxkey-jsonserialize-001.phpt0000664000175000017500000000035713210321137023414 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKey::jsonSerialize() return value --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(1) { ["$maxKey"]=> int(1) } ===DONE=== mongodb-1.3.4/tests/bson/bson-maxkey-jsonserialize-002.phpt0000664000175000017500000000073613210321137023416 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKey::jsonSerialize() with json_encode() --FILE-- new MongoDB\BSON\MaxKey]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$maxKey" : 1 } } {"foo":{"$maxKey":1}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\MaxKey)#%d (%d) { } } ===DONE=== mongodb-1.3.4/tests/bson/bson-maxkey-serialization-001.phpt0000664000175000017500000000053313210321137023404 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKey serialization --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\MaxKey)#%d (%d) { } string(31) "C:19:"MongoDB\BSON\MaxKey":0:{}" object(MongoDB\BSON\MaxKey)#%d (%d) { } ===DONE=== mongodb-1.3.4/tests/bson/bson-maxkey-set_state-001.phpt0000664000175000017500000000033313210321137022520 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKey::__set_state() --FILE-- ===DONE=== --EXPECT-- MongoDB\BSON\MaxKey::__set_state(array( )) ===DONE=== mongodb-1.3.4/tests/bson/bson-maxkey_error-001.phpt0000664000175000017500000000037713210321137021750 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKey cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyMaxKey may not inherit from final class (MongoDB\BSON\MaxKey) in %s on line %d mongodb-1.3.4/tests/bson/bson-maxkeyinterface-001.phpt0000664000175000017500000000037413210321137022415 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MaxKeyInterface is implemented by MongoDB\BSON\MaxKey --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-minkey-001.phpt0000664000175000017500000000122013210321137020521 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKey #001 --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=== --EXPECT-- Test#0 { "min" : { "$minKey" : 1 } } string(29) "{ "min" : { "$minKey" : 1 } }" string(29) "{ "min" : { "$minKey" : 1 } }" bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-minkey-compare-001.phpt0000664000175000017500000000051413210321137022152 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKey comparisons --FILE-- new MongoDB\BSON\MinKey); ?> ===DONE=== --EXPECTF-- bool(true) bool(false) bool(false) ===DONE=== mongodb-1.3.4/tests/bson/bson-minkey-jsonserialize-001.phpt0000664000175000017500000000035713210321137023412 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKey::jsonSerialize() return value --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(1) { ["$minKey"]=> int(1) } ===DONE=== mongodb-1.3.4/tests/bson/bson-minkey-jsonserialize-002.phpt0000664000175000017500000000073613210321137023414 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKey::jsonSerialize() with json_encode() --FILE-- new MongoDB\BSON\MinKey]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$minKey" : 1 } } {"foo":{"$minKey":1}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\MinKey)#%d (%d) { } } ===DONE=== mongodb-1.3.4/tests/bson/bson-minkey-serialization-001.phpt0000664000175000017500000000053313210321137023402 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKey serialization --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\MinKey)#%d (%d) { } string(31) "C:19:"MongoDB\BSON\MinKey":0:{}" object(MongoDB\BSON\MinKey)#%d (%d) { } ===DONE=== mongodb-1.3.4/tests/bson/bson-minkey-set_state-001.phpt0000664000175000017500000000033313210321137022516 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKey::__set_state() --FILE-- ===DONE=== --EXPECT-- MongoDB\BSON\MinKey::__set_state(array( )) ===DONE=== mongodb-1.3.4/tests/bson/bson-minkey_error-001.phpt0000664000175000017500000000037713210321137021746 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKey cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyMinKey may not inherit from final class (MongoDB\BSON\MinKey) in %s on line %d mongodb-1.3.4/tests/bson/bson-minkeyinterface-001.phpt0000664000175000017500000000037413210321137022413 0ustar jmikolajmikola--TEST-- MongoDB\BSON\MinKeyInterface is implemented by MongoDB\BSON\MinKey --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-001.phpt0000664000175000017500000000560213210321137021020 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId #001 --FILE-- my = $sameid; $samearr = array("my" => $sameid); $std = new stdclass; $std->_id = new MongoDB\BSON\ObjectId; $array = array( "_id" => new MongoDB\BSON\ObjectId, "id" => new MongoDB\BSON\ObjectId, "d" => new MongoDB\BSON\ObjectId, ); $pregenerated = new MongoDB\BSON\ObjectId("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() { $id = new MongoDB\BSON\ObjectId("53e28b650640fd3162152de12"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); throws(function() { $id = new MongoDB\BSON\ObjectId("53e28b650640fd3162152dg1"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); throws(function() { $id = new MongoDB\BSON\ObjectId("-3e28b650640fd3162152da1"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); throws(function() { $id = new MongoDB\BSON\ObjectId(" 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.3.4/tests/bson/bson-objectid-002.phpt0000664000175000017500000000061013210321137021013 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId #002 generates ObjectId for null or missing constructor argument --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.3.4/tests/bson/bson-objectid-003.phpt0000664000175000017500000000152613210321137021023 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId #003 construction with string argument --FILE-- value = (string) $value; } public function __toString() { return $this->value; } } $oid = new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603'); $str = new StringObject('53e2a1c40640fd72175d4603'); var_dump($oid); var_dump(new MongoDB\BSON\ObjectId($oid)); var_dump(new MongoDB\BSON\ObjectId($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.3.4/tests/bson/bson-objectid-004.phpt0000664000175000017500000000047613210321137021027 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId #004 Constructor supports uppercase hexadecimal strings --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "56925b7330616224d0000001" } ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-compare-001.phpt0000664000175000017500000000141213210321137022437 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId comparisons --FILE-- new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603')); var_dump(new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603') < new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4604')); var_dump(new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4603') > new MongoDB\BSON\ObjectId('53e2a1c40640fd72175d4602')); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-compare-002.phpt0000664000175000017500000000143213210321137022442 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId comparisons with null bytes --FILE-- new MongoDB\BSON\ObjectId('00e2a1c40640fd72175d4603')); var_dump(new MongoDB\BSON\ObjectId('00e2a1c40640fd72175d4603') < new MongoDB\BSON\ObjectId('00e2a1c40640fd72175d4604')); var_dump(new MongoDB\BSON\ObjectId('00e2a1c40640fd72175d4603') > new MongoDB\BSON\ObjectId('00e2a1c40640fd72175d4602')); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-getTimestamp-001.phpt0000664000175000017500000000047713210321137023466 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId::getTimestamp --FILE-- getTimestamp(); echo $ts, "\n"; echo date_create( "@{$ts}" )->format( "Y-m-d H:i:s" ), "\n"; ?> --EXPECT-- 1447757782 2015-11-17 10:56:22 mongodb-1.3.4/tests/bson/bson-objectid-jsonserialize-001.phpt0000664000175000017500000000044513210321137023677 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId::jsonSerialize() return value --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(1) { ["$oid"]=> string(24) "5820ca4bef62d52d9924d0d8" } ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-jsonserialize-002.phpt0000664000175000017500000000114413210321137023675 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId::jsonSerialize() with json_encode() --FILE-- new MongoDB\BSON\ObjectId('5820ca4bef62d52d9924d0d8')]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$oid" : "5820ca4bef62d52d9924d0d8" } } {"foo":{"$oid":"5820ca4bef62d52d9924d0d8"}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "5820ca4bef62d52d9924d0d8" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-serialization-001.phpt0000664000175000017500000000102413210321137023665 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId serialization --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "576c25db6118fd406e6e6471" } string(82) "C:21:"MongoDB\BSON\ObjectId":48:{a:1:{s:3:"oid";s:24:"576c25db6118fd406e6e6471";}}" object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "576c25db6118fd406e6e6471" } ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-serialization_error-001.phpt0000664000175000017500000000073713210321137025110 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId unserialization requires "oid" string field --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\ObjectId initialization requires "oid" string field ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-serialization_error-002.phpt0000664000175000017500000000137713210321137025112 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId unserialization requires valid hex string --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing ObjectId string: 0123456789abcdefghijklmn OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing ObjectId string: INVALID ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-set_state-001.phpt0000664000175000017500000000046113210321137023007 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId::__set_state() --FILE-- '576c25db6118fd406e6e6471', ])); echo "\n"; ?> ===DONE=== --EXPECTF-- MongoDB\BSON\ObjectId::__set_state(array( %w'oid' => '576c25db6118fd406e6e6471', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-set_state_error-001.phpt0000664000175000017500000000071113210321137024216 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId::__set_state() requires "oid" string field --FILE-- 0]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\ObjectId initialization requires "oid" string field ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid-set_state_error-002.phpt0000664000175000017500000000131713210321137024222 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId::__set_state() requires valid hex string --FILE-- '0123456789abcdefghijklmn']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\ObjectId::__set_state(['oid' => 'INVALID']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing ObjectId string: 0123456789abcdefghijklmn OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing ObjectId string: INVALID ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid_error-001.phpt0000664000175000017500000000070513210321137022230 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId #001 error --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.3.4/tests/bson/bson-objectid_error-002.phpt0000664000175000017500000000041113210321137022223 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyObjectId may not inherit from final class (MongoDB\BSON\ObjectId) in %s on line %d mongodb-1.3.4/tests/bson/bson-objectid_error-003.phpt0000664000175000017500000000124713210321137022234 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectId::__construct() requires valid hex string --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing ObjectId string: 0123456789abcdefghijklmn OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing ObjectId string: INVALID ===DONE=== mongodb-1.3.4/tests/bson/bson-objectidinterface-001.phpt0000664000175000017500000000037613210321137022704 0ustar jmikolajmikola--TEST-- MongoDB\BSON\ObjectIdInterface is implemented by MongoDB\BSON\ObjectId --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-001.phpt0000664000175000017500000000166413210321137020353 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex #001 --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=== --EXPECT-- 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.3.4/tests/bson/bson-regex-002.phpt0000664000175000017500000000043713210321137020351 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex debug handler --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(1) "i" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-003.phpt0000664000175000017500000000167013210321137020352 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex with flags omitted --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=== --EXPECT-- Pattern: regexp Flags: String representation: /regexp/ Test#0 { "regex" : { "$regex" : "regexp", "$options" : "" } } string(54) "{ "regex" : { "$regex" : "regexp", "$options" : "" } }" string(54) "{ "regex" : { "$regex" : "regexp", "$options" : "" } }" bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-004.phpt0000664000175000017500000000045413210321137020352 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex debug handler with flags omitted --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(0) "" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-005.phpt0000664000175000017500000000050113210321137020344 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex initialization will alphabetize flags --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(6) "ilmsux" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-compare-001.phpt0000664000175000017500000000110513210321137021765 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex comparisons (without flags) --FILE-- new MongoDB\BSON\Regex('regexp')); var_dump(new MongoDB\BSON\Regex('regexp') < new MongoDB\BSON\Regex('regexr')); var_dump(new MongoDB\BSON\Regex('regexp') > new MongoDB\BSON\Regex('regexo')); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-compare-002.phpt0000664000175000017500000000132313210321137021770 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex comparisons (with flags) --FILE-- new MongoDB\BSON\Regex('regexp', 'm')); var_dump(new MongoDB\BSON\Regex('regexp', 'm') < new MongoDB\BSON\Regex('regexp', 'x')); var_dump(new MongoDB\BSON\Regex('regexp', 'm') > new MongoDB\BSON\Regex('regexp', 'i')); var_dump(new MongoDB\BSON\Regex('regexp', 'm') > new MongoDB\BSON\Regex('regexp')); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-jsonserialize-001.phpt0000664000175000017500000000046213210321137023225 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::jsonSerialize() return value (without flags) --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(2) { ["$regex"]=> string(7) "pattern" ["$options"]=> string(0) "" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-jsonserialize-002.phpt0000664000175000017500000000046513210321137023231 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::jsonSerialize() return value (with flags) --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(2) { ["$regex"]=> string(7) "pattern" ["$options"]=> string(1) "i" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-jsonserialize-003.phpt0000664000175000017500000000115613210321137023230 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::jsonSerialize() with json_encode() (without flags) --FILE-- new MongoDB\BSON\Regex('pattern')]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$regex" : "pattern", "$options" : "" } } {"foo":{"$regex":"pattern","$options":""}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(7) "pattern" ["flags"]=> string(0) "" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-jsonserialize-004.phpt0000664000175000017500000000116313210321137023227 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::jsonSerialize() with json_encode() (with flags) --FILE-- new MongoDB\BSON\Regex('pattern', 'i')]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$regex" : "pattern", "$options" : "i" } } {"foo":{"$regex":"pattern","$options":"i"}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(7) "pattern" ["flags"]=> string(1) "i" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-serialization-001.phpt0000664000175000017500000000103713210321137023220 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex serialization --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(1) "i" } string(84) "C:18:"MongoDB\BSON\Regex":53:{a:2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:1:"i";}}" object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(1) "i" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-serialization-002.phpt0000664000175000017500000000105213210321137023216 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex serialization with flags omitted --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(0) "" } string(83) "C:18:"MongoDB\BSON\Regex":52:{a:2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:0:"";}}" object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(0) "" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-serialization-003.phpt0000664000175000017500000000055613210321137023227 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex unserialization will alphabetize flags --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(6) "ilmsux" } ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-serialization_error-001.phpt0000664000175000017500000000216313210321137024432 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex unserialization requires "pattern" and "flags" string fields --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Regex initialization requires "pattern" and "flags" string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Regex initialization requires "pattern" and "flags" string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Regex initialization requires "pattern" and "flags" string fields ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-serialization_error-002.phpt0000664000175000017500000000145113210321137024432 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex unserialization does not allow pattern or flags to contain null bytes --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Pattern cannot contain null bytes OK: Got MongoDB\Driver\Exception\InvalidArgumentException Flags cannot contain null bytes ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-set_state-001.phpt0000664000175000017500000000046413210321137022341 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::__set_state() --FILE-- 'regexp', 'flags' => 'i', ])); echo "\n"; ?> ===DONE=== --EXPECTF-- MongoDB\BSON\Regex::__set_state(array( %w'pattern' => 'regexp', %w'flags' => 'i', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-set_state-002.phpt0000664000175000017500000000052513210321137022340 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::__set_state() will alphabetize flags --FILE-- 'regexp', 'flags' => 'xusmli', ])); echo "\n"; ?> ===DONE=== --EXPECTF-- MongoDB\BSON\Regex::__set_state(array( %w'pattern' => 'regexp', %w'flags' => 'ilmsux', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-set_state_error-001.phpt0000664000175000017500000000205513210321137023550 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::__set_state() requires "pattern" and "flags" string fields --FILE-- 'regexp']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Regex::__set_state(['flags' => 'i']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Regex::__set_state(['pattern' => 0, 'flags' => 0]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Regex initialization requires "pattern" and "flags" string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Regex initialization requires "pattern" and "flags" string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Regex initialization requires "pattern" and "flags" string fields ===DONE=== mongodb-1.3.4/tests/bson/bson-regex-set_state_error-002.phpt0000664000175000017500000000133613210321137023552 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::__set_state() does not allow pattern or flags to contain null bytes --FILE-- "regexp\0", 'flags' => 'i']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Regex::__set_state(['pattern' => 'regexp', 'flags' => "i\0"]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Pattern cannot contain null bytes OK: Got MongoDB\Driver\Exception\InvalidArgumentException Flags cannot contain null bytes ===DONE=== mongodb-1.3.4/tests/bson/bson-regex_error-001.phpt0000664000175000017500000000130413210321137021553 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex #001 error --SKIPIF-- --FILE-- getPattern(true); $regexp->getFlags(true); throws(function() { new MongoDB\BSON\Regex; }, "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.3.4/tests/bson/bson-regex_error-002.phpt0000664000175000017500000000037213210321137021560 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyRegex may not inherit from final class (MongoDB\BSON\Regex) in %s on line %d mongodb-1.3.4/tests/bson/bson-regex_error-003.phpt0000664000175000017500000000123013210321137021553 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Regex::__construct() does not allow pattern or flags to contain null bytes --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Pattern cannot contain null bytes OK: Got MongoDB\Driver\Exception\InvalidArgumentException Flags cannot contain null bytes ===DONE=== mongodb-1.3.4/tests/bson/bson-regexinterface-001.phpt0000664000175000017500000000040613210321137022225 0ustar jmikolajmikola--TEST-- MongoDB\BSON\RegexInterface is implemented by MongoDB\BSON\Regex --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-001.phpt0000664000175000017500000000153513210321137021241 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp #001 --FILE-- $timestamp), ); $s = new MongoDB\BSON\Timestamp(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=== --EXPECT-- [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.3.4/tests/bson/bson-timestamp-002.phpt0000664000175000017500000000046713210321137021245 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp debug handler --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-003.phpt0000664000175000017500000000121213210321137021233 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp constructor requires positive unsigned 32-bit integers --FILE-- ===DONE=== --EXPECTF-- Test [2147483647:0] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "2147483647" ["timestamp"]=> string(1) "0" } Test [0:2147483647] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "2147483647" } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-004.phpt0000664000175000017500000000136613210321137021246 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp constructor requires 64-bit integers to be positive unsigned 32-bit integers --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Test [4294967295:0] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "4294967295" ["timestamp"]=> string(1) "0" } Test [0:4294967295] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "4294967295" } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-005.phpt0000664000175000017500000000203613210321137021242 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp constructor requires positive unsigned 32-bit integers (as string) --FILE-- ===DONE=== --EXPECTF-- Test [2147483647:0] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "2147483647" ["timestamp"]=> string(1) "0" } Test [0:2147483647] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "2147483647" } Test [4294967295:0] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "4294967295" ["timestamp"]=> string(1) "0" } Test [0:4294967295] object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "4294967295" } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-compare-001.phpt0000664000175000017500000000160113210321137022657 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp comparisons --FILE-- new MongoDB\BSON\Timestamp(1234, 5678)); // Timestamp is compared first var_dump(new MongoDB\BSON\Timestamp(1234, 5678) < new MongoDB\BSON\Timestamp(1233, 5679)); var_dump(new MongoDB\BSON\Timestamp(1234, 5678) > new MongoDB\BSON\Timestamp(1235, 5677)); // Increment is compared second var_dump(new MongoDB\BSON\Timestamp(1234, 5678) < new MongoDB\BSON\Timestamp(1235, 5678)); var_dump(new MongoDB\BSON\Timestamp(1234, 5678) > new MongoDB\BSON\Timestamp(1233, 5678)); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-getIncrement-001.phpt0000664000175000017500000000074013210321137023660 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::getIncrement() --FILE-- getIncrement()); echo "\n"; } ?> ===DONE=== --EXPECTF-- Test [1234:5678] int(1234) Test [2147483647:0] int(2147483647) Test [0:2147483647] int(0) ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-getTimestamp-001.phpt0000664000175000017500000000074013210321137023677 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::getTimestamp() --FILE-- getTimestamp()); echo "\n"; } ?> ===DONE=== --EXPECTF-- Test [1234:5678] int(5678) Test [2147483647:0] int(0) Test [0:2147483647] int(2147483647) ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-jsonserialize-001.phpt0000664000175000017500000000047413210321137024121 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::jsonSerialize() return value --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(1) { ["$timestamp"]=> array(2) { ["t"]=> int(5678) ["i"]=> int(1234) } } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-jsonserialize-002.phpt0000664000175000017500000000117213210321137024116 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::jsonSerialize() with json_encode() --FILE-- new MongoDB\BSON\Timestamp('1234', '5678')]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$timestamp" : { "t" : 5678, "i" : 1234 } } } {"foo":{"$timestamp":{"t":5678,"i":1234}}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-serialization-001.phpt0000664000175000017500000000270313210321137024112 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp serialization --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } string(95) "C:22:"MongoDB\BSON\Timestamp":60:{a:2:{s:9:"increment";s:4:"1234";s:9:"timestamp";s:4:"5678";}}" object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "2147483647" ["timestamp"]=> string(1) "0" } string(99) "C:22:"MongoDB\BSON\Timestamp":64:{a:2:{s:9:"increment";s:10:"2147483647";s:9:"timestamp";s:1:"0";}}" object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "2147483647" ["timestamp"]=> string(1) "0" } object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "2147483647" } string(99) "C:22:"MongoDB\BSON\Timestamp":64:{a:2:{s:9:"increment";s:1:"0";s:9:"timestamp";s:10:"2147483647";}}" object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "2147483647" } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-serialization-002.phpt0000664000175000017500000000227013210321137024112 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp serialization (64-bit) --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "4294967295" ["timestamp"]=> string(1) "0" } string(99) "C:22:"MongoDB\BSON\Timestamp":64:{a:2:{s:9:"increment";s:10:"4294967295";s:9:"timestamp";s:1:"0";}}" object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(10) "4294967295" ["timestamp"]=> string(1) "0" } object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "4294967295" } string(99) "C:22:"MongoDB\BSON\Timestamp":64:{a:2:{s:9:"increment";s:1:"0";s:9:"timestamp";s:10:"4294967295";}}" object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(1) "0" ["timestamp"]=> string(10) "4294967295" } ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-serialization_error-001.phpt0000664000175000017500000000313713210321137025325 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp unserialization requires "increment" and "timestamp" integer fields --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-serialization_error-002.phpt0000664000175000017500000000274013210321137025325 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp unserialization requires positive unsigned 32-bit integers --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.3.4/tests/bson/bson-timestamp-serialization_error-003.phpt0000664000175000017500000000172213210321137025325 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp unserialization 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.3.4/tests/bson/bson-timestamp-serialization_error-004.phpt0000664000175000017500000000162613210321137025331 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp unserialization requires strings to parse as 64-bit integers --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "1.23" as 64-bit integer increment for MongoDB\BSON\Timestamp initialization OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "5.67" as 64-bit integer timestamp for MongoDB\BSON\Timestamp initialization ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-set_state-001.phpt0000664000175000017500000000131113210321137023222 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::__set_state() --FILE-- $increment, 'timestamp' => $timestamp, ])); echo "\n\n"; } ?> ===DONE=== --EXPECTF-- MongoDB\BSON\Timestamp::__set_state(array( %w'increment' => '1234', %w'timestamp' => '5678', )) MongoDB\BSON\Timestamp::__set_state(array( %w'increment' => '2147483647', %w'timestamp' => '0', )) MongoDB\BSON\Timestamp::__set_state(array( %w'increment' => '0', %w'timestamp' => '2147483647', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-set_state-002.phpt0000664000175000017500000000126513210321137023233 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::__set_state() (64-bit) --SKIPIF-- --FILE-- $increment, 'timestamp' => $timestamp, ])); echo "\n\n"; } ?> ===DONE=== --EXPECTF-- MongoDB\BSON\Timestamp::__set_state(array( %w'increment' => '4294967295', %w'timestamp' => '0', )) MongoDB\BSON\Timestamp::__set_state(array( %w'increment' => '0', %w'timestamp' => '4294967295', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-set_state_error-001.phpt0000664000175000017500000000300213210321137024432 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::__set_state() requires "increment" and "timestamp" integer fields --FILE-- 1234]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['timestamp' => 5678]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['increment' => '1234', 'timestamp' => 5678]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['increment' => 1234, 'timestamp' => '5678']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\Timestamp initialization requires "increment" and "timestamp" integer or numeric string fields ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-set_state_error-002.phpt0000664000175000017500000000260313210321137024441 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::__set_state() requires positive unsigned 32-bit integers --FILE-- -1, 'timestamp' => 5678]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['increment' => -2147483647, 'timestamp' => 5678]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['increment' => 1234, 'timestamp' => -1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['increment' => 1234, 'timestamp' => -2147483647]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===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, -2147483647 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, -2147483647 given ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp-set_state_error-003.phpt0000664000175000017500000000164313210321137024445 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::__set_state() requires 64-bit integers to be positive unsigned 32-bit integers --SKIPIF-- --FILE-- 4294967296, 'timestamp' => 5678]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['increment' => 1234, 'timestamp' => 4294967296]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===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.3.4/tests/bson/bson-timestamp-set_state_error-004.phpt0000664000175000017500000000153713210321137024450 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp::__set_state() requires strings to parse as 64-bit integers --FILE-- '1.23', 'timestamp' => '5678']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { MongoDB\BSON\Timestamp::__set_state(['increment' => '1234', 'timestamp' => '5.67']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "1.23" as 64-bit integer increment for MongoDB\BSON\Timestamp initialization OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "5.67" as 64-bit integer timestamp for MongoDB\BSON\Timestamp initialization ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp_error-001.phpt0000664000175000017500000000067113210321137022452 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp #001 error --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp_error-002.phpt0000664000175000017500000000041613210321137022450 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyTimestamp may not inherit from final class (MongoDB\BSON\Timestamp) in %s on line %d mongodb-1.3.4/tests/bson/bson-timestamp_error-003.phpt0000664000175000017500000000232013210321137022445 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp constructor requires positive unsigned 32-bit integers --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.3.4/tests/bson/bson-timestamp_error-004.phpt0000664000175000017500000000151013210321137022446 0ustar jmikolajmikola--TEST-- MongoDB\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.3.4/tests/bson/bson-timestamp_error-005.phpt0000664000175000017500000000141213210321137022450 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp constructor requires strings to parse as 64-bit integers --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "1.23" as 64-bit integer increment for MongoDB\BSON\Timestamp initialization OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "5.67" as 64-bit integer timestamp for MongoDB\BSON\Timestamp initialization ===DONE=== mongodb-1.3.4/tests/bson/bson-timestamp_error-006.phpt0000664000175000017500000000403113210321137022451 0ustar jmikolajmikola--TEST-- MongoDB\BSON\Timestamp constructor requires integer or string arguments --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer or string, %r(null|NULL)%r given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer or string, %r(double|float)%r given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer or string, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer or string, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer or string, object given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer or string, %r(null|NULL)%r given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer or string, %r(double|float)%r given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer or string, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer or string, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer or string, object given ===DONE=== mongodb-1.3.4/tests/bson/bson-timestampinterface-001.phpt0000664000175000017500000000043213210321137023115 0ustar jmikolajmikola--TEST-- MongoDB\BSON\TimestampInterface is implemented by MongoDB\BSON\Timestamp --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-toCanonicalJSON-001.phpt0000664000175000017500000000166213210321137022163 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toCanonicalExtendedJSON(): Encoding JSON --FILE-- null ], [ 'boolean' => true ], [ 'string' => 'foo' ], [ 'integer' => 123 ], [ 'double' => 1.0, ], [ 'nan' => NAN ], [ 'pos_inf' => INF ], [ 'neg_inf' => -INF ], [ 'array' => [ 'foo', 'bar' ]], [ 'document' => [ 'foo' => 'bar' ]], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toCanonicalExtendedJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { } { "null" : null } { "boolean" : true } { "string" : "foo" } { "integer" : { "$numberInt" : "123" } } { "double" : { "$numberDouble" : "1.0" } } { "nan" : { "$numberDouble" : "NaN" } } { "pos_inf" : { "$numberDouble" : "Infinity" } } { "neg_inf" : { "$numberDouble" : "-Infinity" } } { "array" : [ "foo", "bar" ] } { "document" : { "foo" : "bar" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toCanonicalJSON-002.phpt0000664000175000017500000000270013210321137022156 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toCanonicalExtendedJSON(): Encoding extended JSON types --FILE-- new MongoDB\BSON\ObjectId('56315a7c6118fd1b920270b1') ], [ 'binary' => new MongoDB\BSON\Binary('foo', MongoDB\BSON\Binary::TYPE_GENERIC) ], [ 'date' => new MongoDB\BSON\UTCDateTime(1445990400000) ], [ 'timestamp' => new MongoDB\BSON\Timestamp(1234, 5678) ], [ 'regex' => new MongoDB\BSON\Regex('pattern', 'i') ], [ 'code' => new MongoDB\BSON\Javascript('function() { return 1; }') ], [ 'code_ws' => new MongoDB\BSON\Javascript('function() { return a; }', ['a' => 1]) ], [ 'minkey' => new MongoDB\BSON\MinKey ], [ 'maxkey' => new MongoDB\BSON\MaxKey ], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toCanonicalExtendedJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { "_id" : { "$oid" : "56315a7c6118fd1b920270b1" } } { "binary" : { "$binary" : { "base64": "Zm9v", "subType" : "00" } } } { "date" : { "$date" : { "$numberLong" : "1445990400000" } } } { "timestamp" : { "$timestamp" : { "t" : 5678, "i" : 1234 } } } { "regex" : { "$regularExpression" : { "pattern" : "pattern", "options" : "i" } } } { "code" : { "$code" : "function() { return 1; }" } } { "code_ws" : { "$code" : "function() { return a; }", "$scope" : { "a" : { "$numberInt" : "1" } } } } { "minkey" : { "$minKey" : 1 } } { "maxkey" : { "$maxKey" : 1 } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toCanonicalJSON_error-001.phpt0000664000175000017500000000142713210321137023373 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toCanonicalExtendedJSON(): BSON decoding exceptions --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toCanonicalJSON_error-002.phpt0000664000175000017500000000135113210321137023370 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toCanonicalExtendedJSON(): BSON decoding exceptions for malformed documents --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toCanonicalJSON_error-003.phpt0000664000175000017500000000272413210321137023376 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toCanonicalExtendedJSON(): BSON decoding exceptions for bson_as_canonical_json() failure --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toJSON-001.phpt0000664000175000017500000000166213210321137020353 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toJSON(): Encoding JSON --FILE-- null ], [ 'boolean' => true ], [ 'string' => 'foo' ], [ 'integer' => 123 ], [ 'double' => 1.0, ], /* Note: toJSON() does not properly handle NAN and INF values. * toCanonicalExtendedJSON() or toRelaxedExtendedJSON() should be used * instead. */ [ 'nan' => NAN ], [ 'pos_inf' => INF ], [ 'neg_inf' => -INF ], [ 'array' => [ 'foo', 'bar' ]], [ 'document' => [ 'foo' => 'bar' ]], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { } { "null" : null } { "boolean" : true } { "string" : "foo" } { "integer" : 123 } { "double" : 1.0 } { "nan" : nan } { "pos_inf" : inf } { "neg_inf" : -inf } { "array" : [ "foo", "bar" ] } { "document" : { "foo" : "bar" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toJSON-002.phpt0000664000175000017500000000251013210321137020345 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toJSON(): Encoding extended JSON types --FILE-- new MongoDB\BSON\ObjectId('56315a7c6118fd1b920270b1') ], [ 'binary' => new MongoDB\BSON\Binary('foo', MongoDB\BSON\Binary::TYPE_GENERIC) ], [ 'date' => new MongoDB\BSON\UTCDateTime(1445990400000) ], [ 'timestamp' => new MongoDB\BSON\Timestamp(1234, 5678) ], [ 'regex' => new MongoDB\BSON\Regex('pattern', 'i') ], [ 'code' => new MongoDB\BSON\Javascript('function() { return 1; }') ], [ 'code_ws' => new MongoDB\BSON\Javascript('function() { return a; }', ['a' => 1]) ], [ 'minkey' => new MongoDB\BSON\MinKey ], [ 'maxkey' => new MongoDB\BSON\MaxKey ], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { "_id" : { "$oid" : "56315a7c6118fd1b920270b1" } } { "binary" : { "$binary" : "Zm9v", "$type" : "00" } } { "date" : { "$date" : 1445990400000 } } { "timestamp" : { "$timestamp" : { "t" : 5678, "i" : 1234 } } } { "regex" : { "$regex" : "pattern", "$options" : "i" } } { "code" : { "$code" : "function() { return 1; }" } } { "code_ws" : { "$code" : "function() { return a; }", "$scope" : { "a" : 1 } } } { "minkey" : { "$minKey" : 1 } } { "maxkey" : { "$maxKey" : 1 } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toJSON_error-001.phpt0000664000175000017500000000136513210321137021564 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toJSON(): BSON decoding exceptions --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toJSON_error-002.phpt0000664000175000017500000000130713210321137021561 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toJSON(): BSON decoding exceptions for malformed documents --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toJSON_error-003.phpt0000664000175000017500000000265013210321137021564 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toJSON(): BSON decoding exceptions for bson_as_json() failure --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toPHP-001.phpt0000664000175000017500000000452713210321137020234 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): __pclass must be both instantiatable and Persistable --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('MongoDB\BSON\Unserializable'); $bPersistable = base64_encode('MongoDB\BSON\Persistable'); $tests = array( '{ "foo": "yes", "__pclass": { "$binary": "' . $bMyAbstractDocument . '", "$type": "80" } }', '{ "foo": "yes", "__pclass": { "$binary": "' . $bMyDocument . '", "$type": "80" } }', '{ "foo": "yes", "__pclass": { "$binary": "' . $bUnserializable . '", "$type": "80" } }', '{ "foo": "yes", "__pclass": { "$binary": "' . $bPersistable . '", "$type": "44" } }', ); foreach ($tests as $test) { echo $test, "\n"; var_dump(toPHP(fromJSON($test))); echo "\n"; } ?> ===DONE=== --EXPECTF-- { "foo": "yes", "__pclass": { "$binary": "TXlBYnN0cmFjdERvY3VtZW50", "$type": "80" } } 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": { "$binary": "TXlEb2N1bWVudA==", "$type": "80" } } 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": { "$binary": "TW9uZ29EQlxCU09OXFVuc2VyaWFsaXphYmxl", "$type": "80" } } 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": { "$binary": "TW9uZ29EQlxCU09OXFBlcnNpc3RhYmxl", "$type": "44" } } 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.3.4/tests/bson/bson-toPHP-002.phpt0000664000175000017500000000353113210321137020227 0ustar jmikolajmikola--TEST-- MongoDB\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" : { "$binary" : "TXlEb2N1bWVudA==", "$type" : "80" }, "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.3.4/tests/bson/bson-toPHP-003.phpt0000664000175000017500000002454313210321137020236 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): Tests from serialization specification --FILE-- $value) { $this->$key = $value; } $this->unserialized = true; } } class OurClass implements MongoDB\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('MongoDB\BSON\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": { "$binary": "' . $bMyClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass": { "$binary": "' . $bYourClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass": { "$binary": "' . $bOurClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass": { "$binary": "' . $bYourClass . '", "$type": "44" } }', ), ), 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": { "$binary": "' . $bMyClass . '", "$type": "80" } }', ), ), 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" : { "$binary": "' . $bInterface . '", "$type": "80" } }', ), ), array( 'name' => 'PCLASS OVERRIDES TYPEMAP (1)', 'typemap' => array('root' => 'YourClass'), 'tests' => array( '{ "foo": "yes", "__pclass" : { "$binary": "' . $bMyClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass" : { "$binary": "' . $bOurClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass" : { "$binary": "' . $bTheirClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass" : { "$binary": "' . $bYourClass . '", "$type": "80" } }', ), ), array( 'name' => 'PCLASS OVERRIDES TYPEMAP (2)', 'typemap' => array('root' => 'OurClass'), 'tests' => array( '{ "foo": "yes", "__pclass" : { "$binary": "' . $bTheirClass . '", "$type": "80" } }', ), ), 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" : { "$binary": "' . $bMyClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass" : { "$binary": "' . $bOurClass . '", "$type": "80" } }', ), ), array( 'name' => 'OBJECTS AS STDCLASS', 'typemap' => array('root' => 'object', 'document' => 'object'), 'tests' => array( '{ "foo": "yes", "__pclass" : { "$binary": "' . $bMyClass . '", "$type": "80" } }', '{ "foo": "yes", "__pclass" : { "$binary": "' . $bOurClass . '", "$type": "80" } }', ), ), ); 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": { "$binary": "TXlDbGFzcw==", "$type": "80" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } } { "foo": "yes", "__pclass": { "$binary": "WW91ckNsYXNz", "$type": "80" } } 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": { "$binary": "T3VyQ2xhc3M=", "$type": "80" } } 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": { "$binary": "WW91ckNsYXNz", "$type": "44" } } 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": { "$binary": "TXlDbGFzcw==", "$type": "80" } } Class MyClass does not implement MongoDB\BSON\Unserializable === IS NOT A CONCRETE CLASS === { "foo": "yes" } Class MongoDB\BSON\Unserializable is not instantiatable === IS NOT A CONCRETE CLASS VIA PCLASS === { "foo": "yes", "__pclass" : { "$binary": "TW9uZ29EQlxCU09OXFVuc2VyaWFsaXphYmxl", "$type": "80" } } object(YourClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(27) "MongoDB\BSON\Unserializable" ["type"]=> int(128) } ["unserialized"]=> bool(true) } === PCLASS OVERRIDES TYPEMAP (1) === { "foo": "yes", "__pclass" : { "$binary": "TXlDbGFzcw==", "$type": "80" } } object(YourClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } { "foo": "yes", "__pclass" : { "$binary": "T3VyQ2xhc3M=", "$type": "80" } } 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" : { "$binary": "VGhlaXJDbGFzcw==", "$type": "80" } } object(TheirClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(10) "TheirClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } { "foo": "yes", "__pclass" : { "$binary": "WW91ckNsYXNz", "$type": "80" } } 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" : { "$binary": "VGhlaXJDbGFzcw==", "$type": "80" } } object(TheirClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\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" : { "$binary": "TXlDbGFzcw==", "$type": "80" } } array(2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } } { "foo": "yes", "__pclass" : { "$binary": "T3VyQ2xhc3M=", "$type": "80" } } array(2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(8) "OurClass" ["type"]=> int(128) } } === OBJECTS AS STDCLASS === { "foo": "yes", "__pclass" : { "$binary": "TXlDbGFzcw==", "$type": "80" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } } { "foo": "yes", "__pclass" : { "$binary": "T3VyQ2xhc3M=", "$type": "80" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(8) "OurClass" ["type"]=> int(128) } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toPHP-004.phpt0000664000175000017500000002442713210321137020240 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): BSON array keys should be disregarded during visitation --FILE-- [$value]]); // Alter the key of the BSON array's first element $bson[12] = '1'; var_dump(toPHP($bson)); /* Note that numeric indexes within the HashTable are not accessible without * casting the object to an array. This is because the entries are only * stored with numeric indexes and do not also have string equivalents, as * might be created with zend_symtable_update(). This behavior is not unique * to the driver, as `(object) ['foo']` would demonstrate the same issue. */ var_dump(toPHP($bson, ['array' => 'object'])); var_dump(toPHP($bson, ['array' => 'MyArrayObject'])); echo "\n"; } ?> ===DONE=== --EXPECTF-- Testing NULL visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> NULL } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> NULL } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> NULL } } } Testing boolean visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> bool(true) } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> bool(true) } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> bool(true) } } } Testing integer visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> int(1) } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> int(1) } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> int(1) } } } Testing double visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> float(3.14) } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> float(3.14) } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> float(3.14) } } } Testing string visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> string(3) "foo" } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> string(3) "foo" } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> string(3) "foo" } } } Testing array visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> array(0) { } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(stdClass)#%d (0) { } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(0) { } } } } } Testing stdClass visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(stdClass)#%d (0) { } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(stdClass)#%d (0) { } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(stdClass)#%d (0) { } } } } Testing MongoDB\BSON\Binary visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(3) "foo" ["type"]=> int(0) } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(3) "foo" ["type"]=> int(0) } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(3) "foo" ["type"]=> int(0) } } } } Testing MongoDB\BSON\Decimal128 visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\Decimal128)#%d (1) { ["dec"]=> string(4) "3.14" } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\Decimal128)#%d (1) { ["dec"]=> string(4) "3.14" } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\Decimal128)#%d (1) { ["dec"]=> string(4) "3.14" } } } } Testing MongoDB\BSON\Javascript visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\Javascript)#%d (2) { ["code"]=> string(12) "function(){}" ["scope"]=> NULL } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\Javascript)#%d (2) { ["code"]=> string(12) "function(){}" ["scope"]=> NULL } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\Javascript)#%d (2) { ["code"]=> string(12) "function(){}" ["scope"]=> NULL } } } } Testing MongoDB\BSON\MaxKey visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\MaxKey)#%d (0) { } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\MaxKey)#%d (0) { } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\MaxKey)#%d (0) { } } } } Testing MongoDB\BSON\MinKey visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\MinKey)#%d (0) { } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\MinKey)#%d (0) { } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\MinKey)#%d (0) { } } } } Testing MongoDB\BSON\ObjectId visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\ObjectId)#%d (1) { ["oid"]=> string(24) "586c18d86118fd6c9012dec1" } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\ObjectId)#%d (1) { ["oid"]=> string(24) "586c18d86118fd6c9012dec1" } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\ObjectId)#%d (1) { ["oid"]=> string(24) "586c18d86118fd6c9012dec1" } } } } Testing MongoDB\BSON\Regex visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\Regex)#%d (2) { ["pattern"]=> string(3) "foo" ["flags"]=> string(0) "" } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\Regex)#%d (2) { ["pattern"]=> string(3) "foo" ["flags"]=> string(0) "" } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\Regex)#%d (2) { ["pattern"]=> string(3) "foo" ["flags"]=> string(0) "" } } } } Testing MongoDB\BSON\Timestamp visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\Timestamp)#%d (2) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\Timestamp)#%d (2) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\Timestamp)#%d (2) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } } } } Testing MongoDB\BSON\UTCDateTime visitor function object(stdClass)#%d (1) { ["x"]=> array(1) { [0]=> object(MongoDB\BSON\UTCDateTime)#%d (1) { ["milliseconds"]=> string(13) "1483479256924" } } } object(stdClass)#%d (1) { ["x"]=> object(stdClass)#%d (1) { [%r(0|"0")%r]=> object(MongoDB\BSON\UTCDateTime)#%d (1) { ["milliseconds"]=> string(13) "1483479256924" } } } object(stdClass)#%d (1) { ["x"]=> object(MyArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(1) { [0]=> object(MongoDB\BSON\UTCDateTime)#%d (1) { ["milliseconds"]=> string(13) "1483479256924" } } } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toPHP-006.phpt0000664000175000017500000000302313210321137020227 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): Decodes Binary UUID types with any data length --FILE-- ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(15) "0123456789abcde" ["type"]=> int(3) } } object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(17) "0123456789abcdefg" ["type"]=> int(3) } } object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(15) "0123456789abcde" ["type"]=> int(4) } } object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(17) "0123456789abcdefg" ["type"]=> int(4) } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toPHP_error-001.phpt0000664000175000017500000000525213210321137021441 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): Type classes must be instantiatable and implement Unserializable --FILE-- $class]; printf("Test typeMap: %s\n", json_encode($typeMap)); echo throws(function() use ($bson, $typeMap) { toPHP($bson, $typeMap); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo "\n"; } } ?> ===DONE=== --EXPECT-- Test typeMap: {"array":"MissingClass"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist Test typeMap: {"array":"MyAbstractDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyAbstractDocument is not instantiatable Test typeMap: {"array":"MyDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyDocument does not implement MongoDB\BSON\Unserializable Test typeMap: {"array":"MongoDB\\BSON\\Unserializable"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MongoDB\BSON\Unserializable is not instantiatable Test typeMap: {"document":"MissingClass"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist Test typeMap: {"document":"MyAbstractDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyAbstractDocument is not instantiatable Test typeMap: {"document":"MyDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyDocument does not implement MongoDB\BSON\Unserializable Test typeMap: {"document":"MongoDB\\BSON\\Unserializable"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MongoDB\BSON\Unserializable is not instantiatable Test typeMap: {"root":"MissingClass"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist Test typeMap: {"root":"MyAbstractDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyAbstractDocument is not instantiatable Test typeMap: {"root":"MyDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyDocument does not implement MongoDB\BSON\Unserializable Test typeMap: {"root":"MongoDB\\BSON\\Unserializable"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MongoDB\BSON\Unserializable is not instantiatable ===DONE=== mongodb-1.3.4/tests/bson/bson-toPHP_error-002.phpt0000664000175000017500000000125013210321137021434 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): BSON decoding exceptions --FILE-- getMessage(), "\n"; } } ?> ===DONE=== --EXPECT-- Could not read document from BSON reader Reading document did not exhaust input buffer ===DONE=== mongodb-1.3.4/tests/bson/bson-toPHP_error-003.phpt0000664000175000017500000000131313210321137021435 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): BSON decoding exceptions for malformed documents --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.3.4/tests/bson/bson-toPHP_error-004.phpt0000664000175000017500000000361313210321137021443 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): BSON decoding exceptions for bson_iter_visit_all() failure --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 Detected corrupt BSON data OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected corrupt BSON data OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected corrupt BSON data OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected corrupt BSON data OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected unknown BSON type 0x65 for fieldname "". Are you using the latest driver? ===DONE=== mongodb-1.3.4/tests/bson/bson-toPHP_error-005.phpt0000664000175000017500000000153113210321137021441 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): BSON decoding ignores unsupported BSON types --FILE-- ===DONE=== --EXPECTF-- [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "foo" object(stdClass)#%d (%d) { } [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x0C (DBPointer) for fieldname "foo" object(stdClass)#%d (%d) { } [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x0E (symbol) for fieldname "foo" object(stdClass)#%d (%d) { } ===DONE=== mongodb-1.3.4/tests/bson/bson-toPHP_error-006.phpt0000664000175000017500000000426313210321137021447 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toPHP(): BSON decoding shows multiple warnings --FILE-- ===DONE=== --EXPECTF-- [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u1" [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u2" object(stdClass)#%d (%d) { } [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u1" [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x0E (symbol) for fieldname "s1" object(stdClass)#%d (%d) { } [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u1" [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u2" object(stdClass)#%d (%d) { ["e1"]=> object(stdClass)#%d (0) { } } [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u1" [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u2" object(stdClass)#%d (%d) { ["e1"]=> object(stdClass)#%d (0) { } } [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u1" [%s] PHONGO-BSON: WARNING > Detected unsupported BSON type 0x06 (undefined) for fieldname "u2" object(stdClass)#%d (%d) { ["e1"]=> object(stdClass)#%d (0) { } ["e2"]=> object(stdClass)#%d (0) { } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toRelaxedJSON-001.phpt0000664000175000017500000000160113210321137021651 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toRelaxedExtendedJSON(): Encoding JSON --FILE-- null ], [ 'boolean' => true ], [ 'string' => 'foo' ], [ 'integer' => 123 ], [ 'double' => 1.0, ], [ 'nan' => NAN ], [ 'pos_inf' => INF ], [ 'neg_inf' => -INF ], [ 'array' => [ 'foo', 'bar' ]], [ 'document' => [ 'foo' => 'bar' ]], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toRelaxedExtendedJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { } { "null" : null } { "boolean" : true } { "string" : "foo" } { "integer" : 123 } { "double" : 1.0 } { "nan" : { "$numberDouble" : "NaN" } } { "pos_inf" : { "$numberDouble" : "Infinity" } } { "neg_inf" : { "$numberDouble" : "-Infinity" } } { "array" : [ "foo", "bar" ] } { "document" : { "foo" : "bar" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toRelaxedJSON-002.phpt0000664000175000017500000000263213210321137021657 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toRelaxedExtendedJSON(): Encoding extended JSON types --FILE-- new MongoDB\BSON\ObjectId('56315a7c6118fd1b920270b1') ], [ 'binary' => new MongoDB\BSON\Binary('foo', MongoDB\BSON\Binary::TYPE_GENERIC) ], [ 'date' => new MongoDB\BSON\UTCDateTime(1445990400000) ], [ 'timestamp' => new MongoDB\BSON\Timestamp(1234, 5678) ], [ 'regex' => new MongoDB\BSON\Regex('pattern', 'i') ], [ 'code' => new MongoDB\BSON\Javascript('function() { return 1; }') ], [ 'code_ws' => new MongoDB\BSON\Javascript('function() { return a; }', ['a' => 1]) ], [ 'minkey' => new MongoDB\BSON\MinKey ], [ 'maxkey' => new MongoDB\BSON\MaxKey ], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toRelaxedExtendedJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { "_id" : { "$oid" : "56315a7c6118fd1b920270b1" } } { "binary" : { "$binary" : { "base64": "Zm9v", "subType" : "00" } } } { "date" : { "$date" : "2015-10-28T00:00:00Z" } } { "timestamp" : { "$timestamp" : { "t" : 5678, "i" : 1234 } } } { "regex" : { "$regularExpression" : { "pattern" : "pattern", "options" : "i" } } } { "code" : { "$code" : "function() { return 1; }" } } { "code_ws" : { "$code" : "function() { return a; }", "$scope" : { "a" : 1 } } } { "minkey" : { "$minKey" : 1 } } { "maxkey" : { "$maxKey" : 1 } } ===DONE=== mongodb-1.3.4/tests/bson/bson-toRelaxedJSON_error-001.phpt0000664000175000017500000000142313210321137023064 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toRelaxedExtendedJSON(): BSON decoding exceptions --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toRelaxedJSON_error-002.phpt0000664000175000017500000000134513210321137023070 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toRelaxedExtendedJSON(): BSON decoding exceptions for malformed documents --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-toRelaxedJSON_error-003.phpt0000664000175000017500000000272013210321137023067 0ustar jmikolajmikola--TEST-- MongoDB\BSON\toRelaxedExtendedJSON(): BSON decoding exceptions for bson_as_canonical_json() failure --FILE-- ===DONE=== --EXPECT-- 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.3.4/tests/bson/bson-unknown-001.phpt0000664000175000017500000000112013210321137020723 0ustar jmikolajmikola--TEST-- BSON Serializing a PHP resource should throw exception --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=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-001.phpt0000664000175000017500000000254613210321137021551 0ustar jmikolajmikola--TEST-- MongoDB\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.3.4/tests/bson/bson-utcdatetime-002.phpt0000664000175000017500000000050213210321137021540 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime debug handler --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> %rint\(|string\(13\) "|%r1416445411987%r"|\)%r } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-003.phpt0000664000175000017500000000070413210321137021545 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime construction from 64-bit integer --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1416445411987" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-004.phpt0000664000175000017500000000070313210321137021545 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime constructor defaults to current time --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "%d" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "%d" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-005.phpt0000664000175000017500000000140713210321137021550 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime construction from DateTime --INI-- date.timezone=UTC --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "%d" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1215282385000" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1293894181012" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "2551871655999" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-006.phpt0000664000175000017500000000146413210321137021554 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime construction from DateTimeImmutable --INI-- date.timezone=UTC --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "%d" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1215282385000" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1293894181012" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "2551871655999" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-007.phpt0000664000175000017500000000117013210321137021547 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime constructor truncates floating point values --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1416445411987" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(10) "2147483647" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(4) "1234" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-compare-001.phpt0000664000175000017500000000111713210321137023166 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime comparisons --FILE-- new MongoDB\BSON\UTCDateTime(1234)); var_dump(new MongoDB\BSON\UTCDateTime(1234) < new MongoDB\BSON\UTCDateTime(1235)); var_dump(new MongoDB\BSON\UTCDateTime(1234) > new MongoDB\BSON\UTCDateTime(1233)); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(false) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-int-size-001.phpt0000664000175000017500000000130013210321137023274 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime integer parsing from string --SKIPIF-- --INI-- date.timezone=UTC error_reporting=-1 dislay_errors=1 --FILE-- toDateTime()); ?> ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (1) { ["milliseconds"]=> %r(string\(13\) "|int\()%r1416445411987%r("|\))%r } object(DateTime)#%d (3) { ["date"]=> string(26) "2014-11-20 01:03:31.987000" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-int-size-002.phpt0000664000175000017500000000142213210321137023302 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime integer parsing from number (64-bit) --SKIPIF-- --INI-- date.timezone=UTC error_reporting=-1 dislay_errors=1 --FILE-- toDateTime()); ?> ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (1) { ["milliseconds"]=> %r(string\(13\) "|int\()%r1416445411987%r("|\))%r } object(DateTime)#%d (3) { ["date"]=> string(26) "2014-11-20 01:03:31.987000" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-jsonserialize-001.phpt0000664000175000017500000000053313210321137024422 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::jsonSerialize() return value --FILE-- jsonSerialize()); ?> ===DONE=== --EXPECT-- array(1) { ["$date"]=> array(1) { ["$numberLong"]=> string(13) "1476192866817" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-jsonserialize-002.phpt0000664000175000017500000000116613210321137024426 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::jsonSerialize() with json_encode() --FILE-- new MongoDB\BSON\UTCDateTime(new DateTime('2016-10-11 13:34:26.817 UTC'))]; $json = json_encode($doc); echo toJSON(fromPHP($doc)), "\n"; echo $json, "\n"; var_dump(toPHP(fromJSON($json))); ?> ===DONE=== --EXPECTF-- { "foo" : { "$date" : 1476192866817 } } {"foo":{"$date":{"$numberLong":"1476192866817"}}} object(stdClass)#%d (%d) { ["foo"]=> object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1476192866817" } } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-serialization-001.phpt0000664000175000017500000000226413210321137024421 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime serialization --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(1) "0" } string(71) "C:24:"MongoDB\BSON\UTCDateTime":34:{a:1:{s:12:"milliseconds";s:1:"0";}}" object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(1) "0" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(14) "-1416445411987" } string(85) "C:24:"MongoDB\BSON\UTCDateTime":48:{a:1:{s:12:"milliseconds";s:14:"-1416445411987";}}" object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(14) "-1416445411987" } object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1416445411987" } string(84) "C:24:"MongoDB\BSON\UTCDateTime":47:{a:1:{s:12:"milliseconds";s:13:"1416445411987";}}" object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1416445411987" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-serialization-002.phpt0000664000175000017500000000221313210321137024414 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime serialization (unserialize 32-bit data on 64-bit) --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- string(71) "C:24:"MongoDB\BSON\UTCDateTime":34:{a:1:{s:12:"milliseconds";s:1:"0";}}" object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(1) "0" } string(85) "C:24:"MongoDB\BSON\UTCDateTime":48:{a:1:{s:12:"milliseconds";s:14:"-1416445411987";}}" object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(14) "-1416445411987" } string(84) "C:24:"MongoDB\BSON\UTCDateTime":47:{a:1:{s:12:"milliseconds";s:13:"1416445411987";}}" object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1416445411987" } ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-serialization_error-001.phpt0000664000175000017500000000105213210321137025624 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime unserialization requires "milliseconds" integer or numeric string field --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\UTCDateTime initialization requires "milliseconds" integer or numeric string field ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-serialization_error-002.phpt0000664000175000017500000000117513210321137025633 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime unserialization requires "milliseconds" string to parse as 64-bit integer --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "1234.5678" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-set_state-001.phpt0000664000175000017500000000112313210321137023530 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::__set_state() --FILE-- $milliseconds, ])); echo "\n\n"; } ?> ===DONE=== --EXPECTF-- MongoDB\BSON\UTCDateTime::__set_state(array( %w'milliseconds' => '0', )) MongoDB\BSON\UTCDateTime::__set_state(array( %w'milliseconds' => '-1416445411987', )) MongoDB\BSON\UTCDateTime::__set_state(array( %w'milliseconds' => '1416445411987', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-set_state-002.phpt0000664000175000017500000000125413210321137023536 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::__set_state() (64-bit) --SKIPIF-- --FILE-- $milliseconds, ])); echo "\n\n"; } ?> ===DONE=== --EXPECTF-- MongoDB\BSON\UTCDateTime::__set_state(array( %w'milliseconds' => '0', )) MongoDB\BSON\UTCDateTime::__set_state(array( %w'milliseconds' => '-1416445411987', )) MongoDB\BSON\UTCDateTime::__set_state(array( %w'milliseconds' => '1416445411987', )) ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-set_state_error-001.phpt0000664000175000017500000000102513210321137024742 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::__set_state() requires "milliseconds" integer or numeric string field --FILE-- 1.0]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\BSON\UTCDateTime initialization requires "milliseconds" integer or numeric string field ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-set_state_error-002.phpt0000664000175000017500000000114413210321137024745 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::__set_state() requires "milliseconds" string to parse as 64-bit integer --FILE-- '1234.5678']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; /* TODO: Add tests for out-of-range values once CDRIVER-1377 is resolved */ ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "1234.5678" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-todatetime-001.phpt0000664000175000017500000000053313210321137023700 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::toDateTime() --INI-- date.timezone=America/Los_Angeles --FILE-- toDateTime(); var_dump($datetime->format(DATE_RSS)); ?> ===DONE=== --EXPECT-- string(31) "Thu, 20 Nov 2014 01:03:31 +0000" ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-todatetime-002.phpt0000664000175000017500000000051713210321137023703 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::toDateTime() dumping seconds and microseconds --INI-- date.timezone=UTC --FILE-- toDateTime(); echo $datetime->format('U.u'), "\n"; ?> ===DONE=== --EXPECT-- 1416445411.987000 ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime-tostring-001.phpt0000664000175000017500000000043313210321137023411 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime::__toString() --INI-- date.timezone=America/Los_Angeles --FILE-- ===DONE=== --EXPECT-- string(13) "1416445411987" ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime_error-001.phpt0000664000175000017500000000071113210321137022752 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime requires object argument to implement DateTimeInterface --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected instance of DateTimeInterface, stdClass given ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime_error-002.phpt0000664000175000017500000000043013210321137022751 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyUTCDateTime may not inherit from final class (MongoDB\BSON\UTCDateTime) in %s on line %d mongodb-1.3.4/tests/bson/bson-utcdatetime_error-003.phpt0000664000175000017500000000106713210321137022761 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime constructor requires strings to parse as 64-bit integers --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Error parsing "1234.5678" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetime_error-004.phpt0000664000175000017500000000156213210321137022762 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTime constructor requires integer or string argument --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected integer or string, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected integer or string, array given ===DONE=== mongodb-1.3.4/tests/bson/bson-utcdatetimeinterface-001.phpt0000664000175000017500000000043513210321137023425 0ustar jmikolajmikola--TEST-- MongoDB\BSON\UTCDateTimeInterface is implemented by MongoDB\BSON\UTCDateTime --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/bug0274.phpt0000664000175000017500000000247113210321137017073 0ustar jmikolajmikola--TEST-- Test for PHPC-274: zval_to_bson() should process BSON\Serializable instances --FILE-- "class", "data"); } } class NumericArray implements MongoDB\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.3.4/tests/bson/bug0313.phpt0000664000175000017500000000217513210321137017066 0ustar jmikolajmikola--TEST-- PHPC-313: BSON should throw when encountering 64-bit integer on 32-bit platform --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- 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 MongoDB\Driver\Exception\InvalidArgumentException OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.3.4/tests/bson/bug0325.phpt0000664000175000017500000000070713210321137017070 0ustar jmikolajmikola--TEST-- Test for PHPC-325: Memory leak decoding buffers with multiple documents --FILE-- getMessage(), "\n"; } ?> ===DONE=== --EXPECT-- Reading document did not exhaust input buffer ===DONE=== mongodb-1.3.4/tests/bson/bug0334-001.phpt0000664000175000017500000000111713210321137017362 0ustar jmikolajmikola--TEST-- PHPC-334: Injected __pclass should override a __pclass key in bsonSerialize() return value --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.3.4/tests/bson/bug0334-002.phpt0000664000175000017500000000125113210321137017362 0ustar jmikolajmikola--TEST-- PHPC-334: Encoded BSON should never have multiple __pclass keys --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.3.4/tests/bson/bug0341.phpt0000664000175000017500000000142613210321137017065 0ustar jmikolajmikola--TEST-- PHPC-341: fromJSON() leaks when JSON contains array or object fields --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.3.4/tests/bson/bug0347.phpt0000664000175000017500000000054013210321137017067 0ustar jmikolajmikola--TEST-- Test for PHPC-347: Memory leak decoding empty buffer --FILE-- getMessage(), "\n"; } ?> ===DONE=== --EXPECT-- Could not read document from BSON reader ===DONE=== mongodb-1.3.4/tests/bson/bug0528.phpt0000664000175000017500000000047113210321137017073 0ustar jmikolajmikola--TEST-- PHPC-528: Cannot append reference to BSON --FILE-- &$embedded]; $bson = fromPHP($data); echo toJson(fromPHP($data)), "\n"; ?> ===DONE=== --EXPECT-- { "embedded" : [ "foo" ] } ===DONE=== mongodb-1.3.4/tests/bson/bug0531.phpt0000664000175000017500000000077313210321137017072 0ustar jmikolajmikola--TEST-- PHPC-531: Segfault due to double free by corrupt BSON visitor --FILE-- "world"]); $bson[4] = 1; echo throws(function() use ($bson) { toPHP($bson); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected unknown BSON type 0x31 for fieldname "hello". Are you using the latest driver? ===DONE=== mongodb-1.3.4/tests/bson/bug0544.phpt0000664000175000017500000000425313210321137017073 0ustar jmikolajmikola--TEST-- PHPC-544: Consult SIZEOF_ZEND_LONG for 64-bit integer support --SKIPIF-- --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.3.4/tests/bson/bug0592.phpt0000664000175000017500000000512313210321137017073 0ustar jmikolajmikola--TEST-- PHPC-592: Property name corrupted when unserializing 64-bit integer on 32-bit platform --SKIPIF-- --FILE-- getMessage(), "\n"; } echo "\n"; } ?> ===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": "4294967294" }} MongoDB\Driver\Exception\InvalidArgumentException: Integer overflow detected on your platform: 4294967294 Test { "x": { "$numberLong": "4294967295" }} MongoDB\Driver\Exception\InvalidArgumentException: Integer overflow detected on your platform: 4294967295 Test { "x": { "$numberLong": "9223372036854775807" }} MongoDB\Driver\Exception\InvalidArgumentException: Integer overflow detected on your platform: 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" }} MongoDB\Driver\Exception\InvalidArgumentException: Integer overflow detected on your platform: 4294967294 Test { "longFieldName": { "$numberLong": "4294967295" }} MongoDB\Driver\Exception\InvalidArgumentException: Integer overflow detected on your platform: 4294967295 Test { "longFieldName": { "$numberLong": "9223372036854775807" }} MongoDB\Driver\Exception\InvalidArgumentException: Integer overflow detected on your platform: 9223372036854775807 ===DONE=== mongodb-1.3.4/tests/bson/bug0623.phpt0000664000175000017500000000306613210321137017072 0ustar jmikolajmikola--TEST-- PHPC-623: Numeric keys limited to unsigned 32-bit integer --SKIPIF-- --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=== --EXPECT-- 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.3.4/tests/bson/bug0631.phpt0000664000175000017500000000170513210321137017067 0ustar jmikolajmikola--TEST-- PHPC-631: UTCDateTime::toDateTime() may return object that cannot be serialized --SKIPIF-- --INI-- date.timezone=UTC --FILE-- toDateTime(); $s = serialize($datetime); var_dump($datetime); echo "\n", $s, "\n\n"; var_dump(unserialize($s)); ?> ===DONE=== --EXPECTF-- object(DateTime)#%d (%d) { ["date"]=> string(26) "2016-06-21 20:25:55.123000" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" } O:8:"DateTime":3:{s:4:"date";s:26:"2016-06-21 20:25:55.123000";s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+00:00";} object(DateTime)#%d (%d) { ["date"]=> string(26) "2016-06-21 20:25:55.123000" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" } ===DONE=== mongodb-1.3.4/tests/bson/bug0672.phpt0000664000175000017500000000126213210321137017072 0ustar jmikolajmikola--TEST-- PHPC-672: ObjectId constructor should not modify string argument's memory --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "56925b7330616224d0000001" } string(24) "56925B7330616224D0000001" OK: Got MongoDB\Driver\Exception\InvalidArgumentException string(7) "T123456" ===DONE=== mongodb-1.3.4/tests/bson/bug0894-001.phpt0000664000175000017500000000126413210321137017400 0ustar jmikolajmikola--TEST-- PHPC-849: BSON get_properties handlers leak during gc_possible_root() checks --FILE-- 42]), new MongoDB\BSON\MaxKey, new MongoDB\BSON\MinKey, new MongoDB\BSON\ObjectId, new MongoDB\BSON\Regex('foo', 'i'), new MongoDB\BSON\Timestamp(1234, 5678), new MongoDB\BSON\UTCDateTime, ]; printf("Created array of %d BSON objects\n", count($objects)); gc_collect_cycles(); ?> ===DONE=== --EXPECT-- Created array of 9 BSON objects ===DONE=== mongodb-1.3.4/tests/bson/bug0923-001.phpt0000664000175000017500000000156713210321137017377 0ustar jmikolajmikola--TEST-- PHPC-923: Use zend_string_release() to free class names (type map) --FILE-- 'MissingClass'])); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; var_dump($classes); ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist array(1) { [0]=> string(12) "MissingClass" } ===DONE=== mongodb-1.3.4/tests/bson/bug0923-002.phpt0000664000175000017500000000212213210321137017364 0ustar jmikolajmikola--TEST-- PHPC-923: Use zend_string_release() to free class names (__pclass) --FILE-- ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["x"]=> object(stdClass)#%d (%d) { ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(12) "MissingClass" ["type"]=> int(128) } } } array(1) { [0]=> string(12) "MissingClass" } ===DONE=== mongodb-1.3.4/tests/bson/bug0939-001.phpt0000664000175000017500000000513113210321137017375 0ustar jmikolajmikola--TEST-- PHPC-939: BSON classes should not assign public properties after var_dump() --FILE-- 42]), ['code', 'scope'] ], [ new MongoDB\BSON\MaxKey, [] ], [ new MongoDB\BSON\MinKey, [] ], [ new MongoDB\BSON\ObjectId, ['oid'] ], [ new MongoDB\BSON\Regex('foo', 'i'), ['pattern', 'flags'] ], [ new MongoDB\BSON\Timestamp(1234, 5678), ['increment', 'timestamp'] ], [ new MongoDB\BSON\UTCDateTime, ['milliseconds'] ], ]; foreach ($tests as $test) { list($object, $properties) = $test; var_dump($object); foreach ($properties as $property) { var_dump($object->{$property}); } echo "\n"; } ?> ===DONE=== --EXPECTF-- object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(3) "foo" ["type"]=> int(0) } Notice: Undefined property: MongoDB\BSON\Binary::$data in %s on line %d NULL Notice: Undefined property: MongoDB\BSON\Binary::$type in %s on line %d NULL object(MongoDB\BSON\Decimal128)#%d (%d) { ["dec"]=> string(4) "3.14" } Notice: Undefined property: MongoDB\BSON\Decimal128::$dec in %s on line %d NULL object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(30) "function foo() { return bar; }" ["scope"]=> object(stdClass)#%d (%d) { ["bar"]=> int(42) } } Notice: Undefined property: MongoDB\BSON\Javascript::$code in %s on line %d NULL Notice: Undefined property: MongoDB\BSON\Javascript::$scope in %s on line %d NULL object(MongoDB\BSON\MaxKey)#%d (%d) { } object(MongoDB\BSON\MinKey)#%d (%d) { } object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } Notice: Undefined property: MongoDB\BSON\ObjectId::$oid in %s on line %d NULL object(MongoDB\BSON\Regex)#%d (%d) { ["pattern"]=> string(3) "foo" ["flags"]=> string(1) "i" } Notice: Undefined property: MongoDB\BSON\Regex::$pattern in %s on line %d NULL Notice: Undefined property: MongoDB\BSON\Regex::$flags in %s on line %d NULL object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } Notice: Undefined property: MongoDB\BSON\Timestamp::$increment in %s on line %d NULL Notice: Undefined property: MongoDB\BSON\Timestamp::$timestamp in %s on line %d NULL object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(%d) "%d" } Notice: Undefined property: MongoDB\BSON\UTCDateTime::$milliseconds in %s on line %d NULL ===DONE=== mongodb-1.3.4/tests/bson/bug0974-001.phpt0000664000175000017500000000223513210321137017376 0ustar jmikolajmikola--TEST-- PHPC-974: Converting JSON to BSON to PHP introduces gaps in array indexes --FILE-- ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["myArray"]=> array(1) { [0]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "201700601301102102609060" } } } object(stdClass)#%d (%d) { [%r(0|"0")%r]=> int(1) [%r(1|"1")%r]=> int(2) [%r(2|"2")%r]=> int(3) [%r(3|"3")%r]=> object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1497352886906" } } object(stdClass)#3 (2) { [%r(0|"0")%r]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "55f2b3f1f657b3fa97c9c0a2" } [%r(1|"1")%r]=> object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1497352886906" } } ===DONE=== mongodb-1.3.4/tests/bson/bug1006-001.phpt0000664000175000017500000000176513210321137017370 0ustar jmikolajmikola--TEST-- PHPC-1006: Do not modify memory of Persistable::bsonSerialize() return value --FILE-- data = [ '__pclass' => 'baz', 'foo' => 'bar', ]; } function bsonSerialize() { return $this->data; } function bsonUnserialize(array $data) { } } $obj = new MyClass; var_dump($obj->data); hex_dump(fromPHP($obj)); var_dump($obj->data); ?> ===DONE=== --EXPECT-- array(2) { ["__pclass"]=> string(3) "baz" ["foo"]=> string(3) "bar" } 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..] array(2) { ["__pclass"]=> string(3) "baz" ["foo"]=> string(3) "bar" } ===DONE=== mongodb-1.3.4/tests/bson/bug1006-002.phpt0000664000175000017500000000120213210321137017353 0ustar jmikolajmikola--TEST-- PHPC-1006: Do not skip __pclass in Serializable::bsonSerialize() return value --FILE-- 'baz', 'foo' => 'bar', ]; } } hex_dump(fromPHP(new MyClass)); ?> ===DONE=== --EXPECT-- 0 : 24 00 00 00 02 5f 5f 70 63 6c 61 73 73 00 04 00 [$....__pclass...] 10 : 00 00 62 61 7a 00 02 66 6f 6f 00 04 00 00 00 62 [..baz..foo.....b] 20 : 61 72 00 00 [ar..] ===DONE=== mongodb-1.3.4/tests/bson/bug1053.phpt0000664000175000017500000000047113210321137017065 0ustar jmikolajmikola--TEST-- PHPC-1053: MongoDB\BSON\UTCDateTime's constructor has argument defined as required --FILE-- getParameters()[0]->isOptional()); ?> ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bson/typemap-001.phpt0000664000175000017500000000757113210321137017764 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.3.4/tests/bson/typemap-002.phpt0000664000175000017500000000453613210321137017763 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.3.4/tests/bulk/bug0667.phpt0000664000175000017500000000105513210321137017072 0ustar jmikolajmikola--TEST-- PHPC-667: BulkWrite::insert() does not generate ObjectId if another field has "_id" prefix --SKIPIF-- --FILE-- insert(['_ids' => 1])); var_dump($bulk->insert((object) ['_ids' => 1])); ?> ===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.3.4/tests/bulk/bulkwrite-count-001.phpt0000664000175000017500000000136013210321137021425 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::count() should return the number of operations --SKIPIF-- --FILE-- count()); $bulk->insert(['x' => 1]); var_dump($bulk->count()); $bulk->insert(['x' => 2]); var_dump($bulk->count()); $bulk->update(['x' => 3], ['$set' => ['y' => 3]]); var_dump($bulk->count()); $bulk->update(['x' => 4], ['$set' => ['y' => 4]]); var_dump($bulk->count()); $bulk->delete(['x' => 5]); var_dump($bulk->count()); $bulk->delete(['x' => 6]); var_dump($bulk->count()); ?> ===DONE=== --EXPECT-- int(0) int(1) int(2) int(3) int(4) int(5) int(6) ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-countable-001.phpt0000664000175000017500000000050713210321137022253 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite implements Countable --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-debug-001.phpt0000664000175000017500000000334513210321137021370 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite debug output before execution --SKIPIF-- --FILE-- true], ['ordered' => false], ['bypassDocumentValidation' => true], ['bypassDocumentValidation' => false], ]; foreach ($tests as $options) { var_dump(new MongoDB\Driver\BulkWrite($options)); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(false) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["bypassDocumentValidation"]=> 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) ["bypassDocumentValidation"]=> bool(false) ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-delete-001.phpt0000664000175000017500000000371213210321137021542 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.3.4/tests/bulk/bulkwrite-delete_error-001.phpt0000664000175000017500000000076013210321137022753 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::delete() with invalid options --FILE-- delete(['x' => 1], ['collation' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "collation" option to be array or object, integer given ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-delete_error-002.phpt0000664000175000017500000000141313210321137022750 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::delete() with BSON encoding error (invalid UTF-8 string) --FILE-- delete(['x' => "\xc3\x28"]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->delete(['x' => 1], ['collation' => ['locale' => "\xc3\x28"]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected invalid UTF-8 for fieldname "x": %s OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected invalid UTF-8 for fieldname "locale": %s ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-delete_error-003.phpt0000664000175000017500000000357213210321137022761 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::delete() with BSON encoding error (null bytes in keys) --FILE-- delete(["\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->delete(["x\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->delete(["\0\0\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->delete(['x' => 1], ['collation' => ["\0" => 1]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->delete(['x' => 1], ['collation' => ["x\0" => 1]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->delete(['x' => 1], ['collation' => ["\0\0\0" => 1]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "x". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "x". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-insert-001.phpt0000664000175000017500000000317013210321137021602 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.3.4/tests/bulk/bulkwrite-insert-002.phpt0000664000175000017500000000205613210321137021605 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() with legacy index (pre-2.6 server) --SKIPIF-- --FILE-- ['a.b' => 1], 'name' => 'a.b_1', 'ns' => NS, ]; $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert($legacyIndex); $result = $manager->executeBulkWrite(DATABASE_NAME . '.system.indexes', $bulk); printf("Created %d index(es)\n", $result->getInsertedCount()); $cursor = $manager->executeQuery(DATABASE_NAME . '.system.indexes', new MongoDB\Driver\Query(['name' => 'a.b_1'])); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- Created 1 index(es) array(1) { [0]=> object(stdClass)#%d (%d) { ["v"]=> int(1) ["name"]=> string(5) "a.b_1" ["key"]=> object(stdClass)#%d (%d) { ["a.b"]=> int(1) } ["ns"]=> string(%d) "%s" } } ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-insert-003.phpt0000664000175000017500000000312313210321137021602 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() with legacy index false positive (2.6+ server) --SKIPIF-- --FILE-- ['a' => 1], // Do not attempt to use dots in BSON keys 'name' => 'a_1', 'ns' => NS, ]; $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert($legacyIndex); $result = $manager->executeBulkWrite(NS, $bulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(['name' => 'a_1'])); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- Inserted 1 document(s) array(1) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } ["key"]=> object(stdClass)#%d (%d) { ["a"]=> int(1) } ["name"]=> string(3) "a_1" ["ns"]=> string(32) "phongo.bulk_bulkwrite_insert_003" } } ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-insert-004.phpt0000664000175000017500000000460613210321137021612 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() returns "_id" of inserted document --SKIPIF-- --FILE-- id = $id; } public function bsonSerialize() { return ['id' => $this->id]; } } class MyPersistableId extends MySerializableId implements MongoDB\BSON\Persistable { public function bsonUnserialize(array $data) { $this->id = $data['id']; } } $documents = [ ['x' => 1], ['_id' => new MongoDB\BSON\ObjectId('590b72d606e9660190656a55')], ['_id' => ['foo' => 1]], ['_id' => new MySerializableId('foo')], ['_id' => new MyPersistableId('bar')], ]; $manager = new MongoDB\Driver\Manager(STANDALONE); $bulk = new MongoDB\Driver\BulkWrite(); foreach ($documents as $document) { var_dump($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()); ?> ===DONE=== --EXPECTF-- object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "590b72d606e9660190656a55" } object(stdClass)#%d (%d) { ["foo"]=> int(1) } object(stdClass)#%d (%d) { ["id"]=> string(3) "foo" } object(MyPersistableId)#%d (%d) { ["id"]=> string(3) "bar" } Inserted 5 document(s) array(5) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } ["x"]=> int(1) } [1]=> object(stdClass)#%d (%d) { ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "590b72d606e9660190656a55" } } [2]=> object(stdClass)#%d (%d) { ["_id"]=> object(stdClass)#%d (%d) { ["foo"]=> int(1) } } [3]=> object(stdClass)#%d (%d) { ["_id"]=> object(stdClass)#%d (%d) { ["id"]=> string(3) "foo" } } [4]=> object(stdClass)#%d (%d) { ["_id"]=> object(MyPersistableId)#%d (%d) { ["id"]=> string(3) "bar" } } } ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-insert_error-001.phpt0000664000175000017500000000235213210321137023014 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() with invalid insert document --FILE-- insert(['' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->insert(['x.y' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->insert(['$x' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->insert(["\xc3\x28" => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException document to insert contains invalid key: empty key OK: Got MongoDB\Driver\Exception\InvalidArgumentException document to insert contains invalid key: keys cannot contain ".": "x.y" OK: Got MongoDB\Driver\Exception\InvalidArgumentException document to insert contains invalid key: keys cannot begin with "$": "$x" OK: Got MongoDB\Driver\Exception\InvalidArgumentException document to insert contains invalid key: corrupt BSON ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-insert_error-002.phpt0000664000175000017500000000075513210321137023022 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() with BSON encoding error (invalid UTF-8 string) --FILE-- insert(['x' => "\xc3\x28"]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected invalid UTF-8 for fieldname "x": %s ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-insert_error-003.phpt0000664000175000017500000000201313210321137023010 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() with BSON encoding error (null bytes in keys) --FILE-- insert(["\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->insert(["x\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->insert(["\0\0\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "x". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-insert_error-004.phpt0000664000175000017500000000224213210321137023015 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() with invalid insert document (legacy index) --FILE-- insert(['' => 1, 'key' => ['a.b' => 1], 'name' => 'a.b_1', 'ns' => 'foo']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->insert(['$x' => 1, 'key' => ['a.b' => 1], 'name' => 'a.b_1', 'ns' => 'foo']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->insert(["\xc3\x28" => 1, 'key' => ['a.b' => 1], 'name' => 'a.b_1', 'ns' => 'foo']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException legacy index document contains invalid key: empty key OK: Got MongoDB\Driver\Exception\InvalidArgumentException legacy index document contains invalid key: keys cannot begin with "$": "$x" OK: Got MongoDB\Driver\Exception\InvalidArgumentException legacy index document contains invalid key: corrupt BSON ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-update-001.phpt0000664000175000017500000000473613210321137021571 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.3.4/tests/bulk/bulkwrite-update_error-001.phpt0000664000175000017500000000245713210321137023000 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::update() with invalid replacement document --FILE-- update(['x' => 1], ['' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['x.y' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['y' => ['$x' => 1]]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ["\xc3\x28" => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException replacement document contains invalid key: empty key OK: Got MongoDB\Driver\Exception\InvalidArgumentException replacement document contains invalid key: keys cannot contain ".": "x.y" OK: Got MongoDB\Driver\Exception\InvalidArgumentException replacement document contains invalid key: keys cannot begin with "$": "$x" OK: Got MongoDB\Driver\Exception\InvalidArgumentException replacement document contains invalid key: corrupt BSON ===DONE===mongodb-1.3.4/tests/bulk/bulkwrite-update_error-002.phpt0000664000175000017500000000245013210321137022772 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::update() with invalid update document --FILE-- update(['x' => 1], ['$set' => ['x' => ['' => 1]]]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['$set' => ['x' => ["\xc3\x28" => 1]]]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; /* This newObj argument mixes an update and replacement document, but * php_phongo_bulkwrite_update_has_operators() will categorize it as an update * due to the presence of an atomic operator. As such, _mongoc_validate_update() * will report the error. */ echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['$set' => ['y' => 1], 'z' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException update document contains invalid key: empty key OK: Got MongoDB\Driver\Exception\InvalidArgumentException update document contains invalid key: corrupt BSON OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid key 'z': update only works with $ operators ===DONE===mongodb-1.3.4/tests/bulk/bulkwrite-update_error-003.phpt0000664000175000017500000000210213210321137022765 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::update() with invalid options --FILE-- update(['x' => 1], ['y' => 1], ['multi' => true]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['y' => 1], ['collation' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['$set' => ['y' => 1]], ['collation' => 1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Replacement document conflicts with true "multi" option OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "collation" option to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "collation" option to be array or object, integer given ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-update_error-004.phpt0000664000175000017500000000246513210321137023002 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::update() with BSON encoding error (invalid UTF-8 string) --FILE-- update(['x' => "\xc3\x28"], ['x' => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['x' => "\xc3\x28"]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['$set' => ['x' => "\xc3\x28"]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['y' => 1], ['collation' => ['locale' => "\xc3\x28"]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected invalid UTF-8 for fieldname "x": %s OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected invalid UTF-8 for fieldname "x": %s OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected invalid UTF-8 for fieldname "x": %s OK: Got MongoDB\Driver\Exception\UnexpectedValueException Detected invalid UTF-8 for fieldname "locale": %s ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite-update_error-005.phpt0000664000175000017500000000537613210321137023007 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::update() with BSON encoding error (null bytes in keys) --FILE-- update(["\0" => 1], ['x' => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(["x\0" => 1], ['x' => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(["\0\0\0" => 1], ['x' => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ["\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ["x\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ["\0\0\0" => 1]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['y' => 1], ['collation' => ["\0" => 1]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['y' => 1], ['collation' => ["x\0" => 1]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n\n"; echo throws(function() use ($bulk) { $bulk->update(['x' => 1], ['y' => 1], ['collation' => ["\0\0\0" => 1]]); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "x". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "x". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "x". OK: Got MongoDB\Driver\Exception\UnexpectedValueException BSON keys cannot contain null bytes. Unexpected null byte after "". ===DONE=== mongodb-1.3.4/tests/bulk/bulkwrite_error-001.phpt0000664000175000017500000000042413210321137021510 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyBulkWrite may not inherit from final class (MongoDB\Driver\BulkWrite) in %s on line %d mongodb-1.3.4/tests/bulk/bulkwrite_error-002.phpt0000664000175000017500000000153213210321137021512 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite cannot be executed multiple times --SKIPIF-- --FILE-- insert(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); echo throws(function() use ($manager, $bulk) { $result = $manager->executeBulkWrite(NS, $bulk); }, 'MongoDB\Driver\Exception\BulkWriteException'), "\n"; ?> ===DONE=== --EXPECTF-- Inserted 1 document(s) OK: Got MongoDB\Driver\Exception\BulkWriteException BulkWrite objects may only be executed once and this instance has already been executed ===DONE=== mongodb-1.3.4/tests/bulk/write-0001.phpt0000664000175000017500000000467113210321137017511 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) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["bypassDocumentValidation"]=> NULL ["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) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(true) ["server_id"]=> int(1) ["write_concern"]=> NULL } Inserted: 3 Deleted: 1 Updated: 1 Upserted: 0 ===DONE=== mongodb-1.3.4/tests/bulk/write-0002.phpt0000664000175000017500000000333413210321137017505 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) ["bypassDocumentValidation"]=> NULL ["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) ["bypassDocumentValidation"]=> NULL ["executed"]=> bool(true) ["server_id"]=> int(1) ["write_concern"]=> array(%d) { ["w"]=> int(1) ["wtimeout"]=> int(1000) } } Inserted 2 documents to %s hannes: %s hayley: %s ===DONE=== mongodb-1.3.4/tests/command/command-ctor-001.phpt0000664000175000017500000000420113210321137021330 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Command construction 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'))); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'findAndModify' => COLLECTION_NAME, 'query' => ['_id' => 'foo'], 'update' => $document, 'upsert' => true, 'new' => true, ])); var_dump($cursor->toArray()[0]->value); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'aggregate' => COLLECTION_NAME, 'pipeline' => [ ['$match' => $document], ], ])); var_dump($cursor->toArray()[0]->result[0]); ?> ===DONE=== --EXPECTF-- 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 } } } 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.3.4/tests/command/command_error-001.phpt0000664000175000017500000000041213210321137021574 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Command cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyCommand may not inherit from final class (MongoDB\Driver\Command) in %s on line %d mongodb-1.3.4/tests/connect/bug0720.phpt0000664000175000017500000000210413210321137017550 0ustar jmikolajmikola--TEST-- PHPC-720: Do not persist SSL streams to avoid SSL reinitialization errors --SKIPIF-- --FILE-- true, 'ca_file' => $SSL_DIR . '/ca.pem', ]; $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); unset($manager, $cursor); $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/bug1045.phpt0000664000175000017500000000146013210321137017555 0ustar jmikolajmikola--TEST-- PHPC-1045: Segfault if username is not provided for SCRAM-SHA-1 authMechanism --SKIPIF-- --FILE-- 'SCRAM-SHA-1', 'ssl' => false]); // Execute a basic ping command to trigger connection initialization echo throws(function() use ($m) { $m->executeCommand('admin', new MongoDB\Driver\Command(['ping'=>1])); }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\RuntimeException SCRAM Failure: username is not set ===DONE=== mongodb-1.3.4/tests/connect/replicaset-seedlist-001.phpt0000664000175000017500000000131713210321137022732 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.3.4/tests/connect/replicaset-seedlist-002.phpt0000664000175000017500000000131513210321137022731 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.3.4/tests/connect/standalone-auth-0001.phpt0000664000175000017500000000215513210321137022135 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.3.4/tests/connect/standalone-auth-0002.phpt0000664000175000017500000000153213210321137022134 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.3.4/tests/connect/standalone-plain-0001.phpt0000664000175000017500000000372713210321137022305 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/?authSource=%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.3.4/tests/connect/standalone-plain-0002.phpt0000664000175000017500000000324213210321137022276 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/?authSource=%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.3.4/tests/connect/standalone-ssl-no_verify-001.phpt0000664000175000017500000000121213210321137023704 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and no host/cert verification --SKIPIF-- --FILE-- true, "weak_cert_validation" => true, ]; $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/standalone-ssl-no_verify-002.phpt0000664000175000017500000000143013210321137023707 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and no host/cert verification (context options) --SKIPIF-- --FILE-- stream_context_create([ 'ssl' => [ 'allow_invalid_hostname' => true, 'allow_self_signed' => true, // "weak_cert_validation" alias ], ]), ]; $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/standalone-ssl-verify_cert-001.phpt0000664000175000017500000000145313210321137024234 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and cert verification --SKIPIF-- --FILE-- true, 'weak_cert_validation' => false, 'ca_file' => $SSL_DIR . '/ca.pem', ]; $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/standalone-ssl-verify_cert-002.phpt0000664000175000017500000000173313210321137024236 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and cert verification (context options) --SKIPIF-- --FILE-- stream_context_create([ 'ssl' => [ // libmongoc does not allow the hostname to be overridden as "server" 'allow_invalid_hostname' => true, 'allow_self_signed' => false, // "weak_cert_validation" alias 'cafile' => $SSL_DIR . '/ca.pem', // "ca_file" alias ], ]), ]; $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/standalone-ssl-verify_cert-error-001.phpt0000664000175000017500000000173713210321137025370 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and cert verification error --SKIPIF-- --FILE-- true, 'weak_cert_validation' => false, ]; echo throws(function() use ($driverOptions) { $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException', 'executeCommand'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException thrown from executeCommand No suitable servers found (`serverSelectionTryOnce` set): [%s calling ismaster on '%s:%d'] ===DONE=== mongodb-1.3.4/tests/connect/standalone-ssl-verify_cert-error-002.phpt0000664000175000017500000000216513210321137025365 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and cert verification error (context options) --SKIPIF-- --FILE-- stream_context_create([ 'ssl' => [ // libmongoc does not allow the hostname to be overridden as "server" 'allow_invalid_hostname' => true, 'allow_self_signed' => false, // "weak_cert_validation" alias ], ]), ]; echo throws(function() use ($driverOptions) { $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException', 'executeCommand'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException thrown from executeCommand No suitable servers found (`serverSelectionTryOnce` set): [%s calling ismaster on '%s:%d'] ===DONE=== mongodb-1.3.4/tests/connect/standalone-x509-auth-001.phpt0000664000175000017500000000152113210321137022554 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and X509 auth --SKIPIF-- --FILE-- true, 'weak_cert_validation' => false, 'ca_file' => $SSL_DIR . '/ca.pem', 'pem_file' => $SSL_DIR . '/client.pem', ]; $manager = new MongoDB\Driver\Manager(STANDALONE_X509, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/standalone-x509-auth-002.phpt0000664000175000017500000000203613210321137022557 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and X509 auth (stream context) --SKIPIF-- --FILE-- stream_context_create([ 'ssl' => [ // libmongoc does not allow the hostname to be overridden as "server" 'allow_invalid_hostname' => true, 'allow_self_signed' => false, // "weak_cert_validation" alias 'cafile' => $SSL_DIR . '/ca.pem', // "ca_file" alias 'local_cert' => $SSL_DIR . '/client.pem', // "pem_file" alias ], ]), ]; $manager = new MongoDB\Driver\Manager(STANDALONE_X509, ['ssl' => true], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/standalone-x509-error-0001.phpt0000664000175000017500000000262013210321137023025 0ustar jmikolajmikola--TEST-- X509 connection should not reuse previous stream after an auth failure --SKIPIF-- --FILE-- true, 'ca_file' => $SSL_DIR . '/ca.pem', 'pem_file' => $SSL_DIR . '/client.pem', ]; // Wrong username for X509 authentication $parsed = parse_url(STANDALONE_X509); $dsn = sprintf('mongodb://username@%s:%d/?ssl=true&authMechanism=MONGODB-X509', $parsed['host'], $parsed['port']); // Both should fail with auth failure, without reusing the previous stream for ($i = 0; $i < 2; $i++) { echo throws(function() use ($dsn, $driverOptions) { $manager = new MongoDB\Driver\Manager($dsn, [], $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); }, 'MongoDB\Driver\Exception\AuthenticationException', 'executeCommand'), "\n"; } ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\AuthenticationException thrown from executeCommand auth failed OK: Got MongoDB\Driver\Exception\AuthenticationException thrown from executeCommand auth failed ===DONE=== mongodb-1.3.4/tests/connect/standalone-x509-extract_username-001.phpt0000664000175000017500000000202213210321137025161 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and X509 auth and username retrieved from cert --SKIPIF-- --FILE-- true, 'weak_cert_validation' => false, 'ca_file' => $SSL_DIR . '/ca.pem', 'pem_file' => $SSL_DIR . '/client.pem', ]; $uriOptions = ['authMechanism' => 'MONGODB-X509', 'ssl' => true]; $parsed = parse_url(STANDALONE_X509); $uri = sprintf('mongodb://%s:%d', $parsed['host'], $parsed['port']); $manager = new MongoDB\Driver\Manager($uri, $uriOptions, $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/connect/standalone-x509-extract_username-002.phpt0000664000175000017500000000233713210321137025173 0ustar jmikolajmikola--TEST-- Connect to MongoDB with SSL and X509 auth and username retrieved from cert (stream context) --SKIPIF-- --FILE-- stream_context_create([ 'ssl' => [ // libmongoc does not allow the hostname to be overridden as "server" 'allow_invalid_hostname' => true, 'allow_self_signed' => false, // "weak_cert_validation" alias 'cafile' => $SSL_DIR . '/ca.pem', // "ca_file" alias 'local_cert' => $SSL_DIR . '/client.pem', // "pem_file" alias ], ]), ]; $uriOptions = ['authMechanism' => 'MONGODB-X509', 'ssl' => true]; $parsed = parse_url(STANDALONE_X509); $uri = sprintf('mongodb://%s:%d', $parsed['host'], $parsed['port']); $manager = new MongoDB\Driver\Manager($uri, $uriOptions, $driverOptions); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/cursor/bug0671-001.phpt0000664000175000017500000000122613210321137017743 0ustar jmikolajmikola--TEST-- PHPC-671: Segfault if Manager is already freed when destructing live Cursor --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); unset($manager); unset($cursor); ?> ===DONE=== --EXPECT-- ===DONE=== mongodb-1.3.4/tests/cursor/bug0732-001.phpt0000664000175000017500000000165713210321137017751 0ustar jmikolajmikola--TEST-- PHPC-732: Possible mongoc_client_t use-after-free with Cursor wrapped in generator --SKIPIF-- --FILE-- $value) { yield $key => $value; } } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); $generator = wrapCursor($cursor); foreach ($generator as $value) { echo "Exiting during first iteration on generator\n"; exit(0); } ?> ===DONE=== --EXPECT-- Exiting during first iteration on generator mongodb-1.3.4/tests/cursor/bug0849-001.phpt0000664000175000017500000000177613210321137017764 0ustar jmikolajmikola--TEST-- PHPC-849: Cursor::setTypeMap() leaks current element if called during iteration --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); $cursor->setTypeMap(['root' => 'stdClass']); foreach ($cursor as $i => $document) { // Type map will apply to the next iteration, since current element is already converted $cursor->setTypeMap(['root' => ($i % 2 ? 'stdClass' : 'array')]); var_dump($document); } ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["_id"]=> int(1) } array(1) { ["_id"]=> int(2) } object(stdClass)#%d (%d) { ["_id"]=> int(3) } ===DONE=== mongodb-1.3.4/tests/cursor/bug0924-001.phpt0000664000175000017500000000270213210321137017744 0ustar jmikolajmikola--TEST-- PHPC-924: Cursor::setTypeMap() may unnecessarily convert first BSON document (type map) --SKIPIF-- --FILE-- data['_id'] = $id; } public function bsonSerialize() { return (object) $this->data; } public function bsonUnserialize(array $data) { printf("%s called for ID: %s\n", __METHOD__, $data['_id']); $this->data = $data; } } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(new MyDocument('a')); $bulk->insert(new MyDocument('b')); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); $cursor->setTypeMap(['root' => 'MyDocument']); foreach ($cursor as $i => $document) { var_dump($document); } ?> ===DONE=== --EXPECTF-- MyDocument::bsonUnserialize called for ID: a object(MyDocument)#%d (%d) { ["data":"MyDocument":private]=> array(1) { ["_id"]=> string(1) "a" } } MyDocument::bsonUnserialize called for ID: b object(MyDocument)#%d (%d) { ["data":"MyDocument":private]=> array(1) { ["_id"]=> string(1) "b" } } ===DONE=== mongodb-1.3.4/tests/cursor/bug0924-002.phpt0000664000175000017500000000354113210321137017747 0ustar jmikolajmikola--TEST-- PHPC-924: Cursor::setTypeMap() may unnecessarily convert first BSON document (__pclass) --SKIPIF-- --FILE-- data['_id'] = $id; } public function bsonSerialize() { return (object) $this->data; } public function bsonUnserialize(array $data) { printf("%s called for ID: %s\n", __METHOD__, $data['_id']); $this->data = $data; } } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(new MyDocument('a')); $bulk->insert(new MyDocument('b')); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); /* This type map will have no effect on the query result, since the document * only contains an ID, but it allows us to test for unnecessary conversion. */ $cursor->setTypeMap(['array' => 'array']); foreach ($cursor as $i => $document) { var_dump($document); } ?> ===DONE=== --EXPECTF-- MyDocument::bsonUnserialize called for ID: a object(MyDocument)#%d (%d) { ["data":"MyDocument":private]=> array(2) { ["_id"]=> string(1) "a" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(10) "MyDocument" ["type"]=> int(128) } } } MyDocument::bsonUnserialize called for ID: b object(MyDocument)#%d (%d) { ["data":"MyDocument":private]=> array(2) { ["_id"]=> string(1) "b" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(10) "MyDocument" ["type"]=> int(128) } } } ===DONE=== mongodb-1.3.4/tests/cursor/cursor-IteratorIterator-001.phpt0000664000175000017500000000150413210321137023465 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor query result iteration through IteratorIterator --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1))); foreach (new IteratorIterator($cursor) as $document) { var_dump($document); } ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(1) } ===DONE=== mongodb-1.3.4/tests/cursor/cursor-IteratorIterator-002.phpt0000664000175000017500000000176213210321137023474 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor command result iteration through IteratorIterator --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $command = new MongoDB\Driver\Command(array( 'aggregate' => COLLECTION_NAME, 'pipeline' => array( array('$match' => array('x' => 1)), ), 'cursor' => new stdClass, )); $cursor = $manager->executeCommand(DATABASE_NAME, $command); foreach (new IteratorIterator($cursor) as $document) { var_dump($document); } ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(1) } ===DONE=== mongodb-1.3.4/tests/cursor/cursor-IteratorIterator-003.phpt0000664000175000017500000000202413210321137023465 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor iteration beyond last document (find command) --SKIPIF-- --FILE-- insert(['_id' => 1]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); $iterator = new IteratorIterator($cursor); $iterator->rewind(); var_dump($iterator->current()); $iterator->next(); var_dump($iterator->current()); // libmongoc throws on superfluous iteration of find command cursor (CDRIVER-1234) echo throws(function() use ($iterator) { $iterator->next(); }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["_id"]=> int(1) } NULL OK: Got MongoDB\Driver\Exception\RuntimeException Cannot advance a completed or failed cursor. ===DONE=== mongodb-1.3.4/tests/cursor/cursor-IteratorIterator-004.phpt0000664000175000017500000000206313210321137023471 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor iteration beyond last document (OP_QUERY) --SKIPIF-- --FILE-- insert(['_id' => 1]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array(), array('batchSize' => 2))); $iterator = new IteratorIterator($cursor); $iterator->rewind(); var_dump($iterator->current()); $iterator->next(); var_dump($iterator->current()); // libmongoc throws on superfluous iteration of OP_QUERY cursor (CDRIVER-1234) echo throws(function() use ($iterator) { $iterator->next(); }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["_id"]=> int(1) } NULL OK: Got MongoDB\Driver\Exception\RuntimeException Cannot advance a completed or failed cursor. ===DONE=== mongodb-1.3.4/tests/cursor/cursor-NoRewindIterator-001.phpt0000664000175000017500000000314713210321137023426 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor query result iteration through NoRewindIterator --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1))); /* IteratorIterator requires either rewind() or next() to be called at least * once to populate its current.data pointer, which valid() checks. Since next() * would skip the first element and NoRewindIterator::rewind() is a NOP, we must * explicitly call IteratorIterator::rewind() before composing it. */ $iteratorIterator = new IteratorIterator($cursor); $iteratorIterator->rewind(); $noRewindIterator = new NoRewindIterator($iteratorIterator); foreach ($noRewindIterator as $document) { var_dump($document); } /* NoRewindIterator::rewind() is a NOP, so attempting to iterate a second time * or calling rewind() directly accomplishes nothing. That said, it does avoid * the exception one would otherwise get invoking the rewind handler after * iteration has started. */ foreach ($noRewindIterator as $document) { var_dump($document); } $noRewindIterator->rewind(); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(1) } ===DONE=== mongodb-1.3.4/tests/cursor/cursor-destruct-001.phpt0000664000175000017500000000264013210321137022021 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor destruct should kill a live cursor --SKIPIF-- --FILE-- executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(array('serverStatus' => 1))); $result = current($cursor->toArray()); if (isset($result->metrics->cursor->open->total)) { return $result->metrics->cursor->open->total; } if (isset($result->cursors->totalOpen)) { return $result->cursors->totalOpen; } throw new RuntimeException('Could not find number of open cursors in serverStatus'); } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1)); $bulk->insert(array('_id' => 2)); $bulk->insert(array('_id' => 3)); $manager->executeBulkWrite(NS, $bulk); $numOpenCursorsBeforeQuery = getNumOpenCursors($manager); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array(), array('batchSize' => 2))); var_dump($cursor->isDead()); var_dump(getNumOpenCursors($manager) == $numOpenCursorsBeforeQuery + 1); unset($cursor); var_dump(getNumOpenCursors($manager) == $numOpenCursorsBeforeQuery); ?> ===DONE=== --EXPECT-- bool(false) bool(true) bool(true) ===DONE=== mongodb-1.3.4/tests/cursor/cursor-get_iterator-001.phpt0000664000175000017500000000247413210321137022661 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor get_iterator handler does not yield multiple iterators (foreach) --SKIPIF-- --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); echo "\nFirst foreach statement:\n"; foreach ($cursor as $document) { var_dump($document); } echo "\nSecond foreach statement:\n"; try { foreach ($cursor as $document) { echo "FAILED: get_iterator should not yield multiple iterators\n"; } } catch (MongoDB\Driver\Exception\LogicException $e) { printf("LogicException: %s\n", $e->getMessage()); } ?> ===DONE=== --EXPECTF-- Inserted: 3 First foreach statement: object(stdClass)#%d (1) { ["_id"]=> int(0) } object(stdClass)#%d (1) { ["_id"]=> int(1) } object(stdClass)#%d (1) { ["_id"]=> int(2) } Second foreach statement: LogicException: Cursors cannot yield multiple iterators ===DONE=== mongodb-1.3.4/tests/cursor/cursor-get_iterator-002.phpt0000664000175000017500000000237713210321137022664 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor get_iterator handler does not yield multiple iterators (IteratorIterator) --SKIPIF-- --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); echo "\nFirst IteratorIterator wrapping:\n"; var_dump(new IteratorIterator($cursor)); echo "\nSecond IteratorIterator wrapping:\n"; try { var_dump(new IteratorIterator($cursor)); } catch (MongoDB\Driver\Exception\LogicException $e) { printf("LogicException: %s\n", $e->getMessage()); } ?> ===DONE=== --EXPECTF-- Inserted: 3 First IteratorIterator wrapping: object(IteratorIterator)#%d (0) { } Second IteratorIterator wrapping: LogicException: Cursors cannot yield multiple iterators ===DONE=== mongodb-1.3.4/tests/cursor/cursor-get_iterator-003.phpt0000664000175000017500000000241513210321137022656 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor get_iterator handler does not yield multiple iterators (toArray()) --SKIPIF-- --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); echo "\nFirst Cursor::toArray():\n"; var_dump($cursor->toArray()); echo "\nSecond Cursor::toArray():\n"; try { var_dump($cursor->toArray()); } catch (MongoDB\Driver\Exception\LogicException $e) { printf("LogicException: %s\n", $e->getMessage()); } ?> ===DONE=== --EXPECTF-- Inserted: 3 First Cursor::toArray(): array(3) { [0]=> object(stdClass)#%d (1) { ["_id"]=> int(0) } [1]=> object(stdClass)#%d (1) { ["_id"]=> int(1) } [2]=> object(stdClass)#%d (1) { ["_id"]=> int(2) } } Second Cursor::toArray(): LogicException: Cursors cannot yield multiple iterators ===DONE=== mongodb-1.3.4/tests/cursor/cursor-getmore-001.phpt0000664000175000017500000000163213210321137021626 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor query result iteration with batchSize requiring getmore with full batches --SKIPIF-- --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array(), array('batchSize' => 2))); foreach ($cursor as $i => $document) { printf("%d => {_id: %d}\n", $i, $document->_id); } ?> ===DONE=== --EXPECT-- Inserted: 6 0 => {_id: 0} 1 => {_id: 1} 2 => {_id: 2} 3 => {_id: 3} 4 => {_id: 4} 5 => {_id: 5} ===DONE=== mongodb-1.3.4/tests/cursor/cursor-getmore-002.phpt0000664000175000017500000000162013210321137021624 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor query result iteration with batchSize requiring getmore with non-full batches --SKIPIF-- --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array(), array('batchSize' => 2))); foreach ($cursor as $i => $document) { printf("%d => {_id: %d}\n", $i, $document->_id); } ?> ===DONE=== --EXPECT-- Inserted: 5 0 => {_id: 0} 1 => {_id: 1} 2 => {_id: 2} 3 => {_id: 3} 4 => {_id: 4} ===DONE=== mongodb-1.3.4/tests/cursor/cursor-getmore-003.phpt0000664000175000017500000000207713210321137021634 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor command result iteration with batchSize requiring getmore with full batches --SKIPIF-- --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $command = new MongoDB\Driver\Command(array( 'aggregate' => COLLECTION_NAME, 'pipeline' => array( array('$match' => new stdClass), ), 'cursor' => array('batchSize' => 2), )); $cursor = $manager->executeCommand(DATABASE_NAME, $command); foreach ($cursor as $i => $document) { printf("%d => {_id: %d}\n", $i, $document->_id); } ?> ===DONE=== --EXPECT-- Inserted: 6 0 => {_id: 0} 1 => {_id: 1} 2 => {_id: 2} 3 => {_id: 3} 4 => {_id: 4} 5 => {_id: 5} ===DONE=== mongodb-1.3.4/tests/cursor/cursor-getmore-004.phpt0000664000175000017500000000206513210321137021632 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor command result iteration with batchSize requiring getmore with non-full batches --SKIPIF-- --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $command = new MongoDB\Driver\Command(array( 'aggregate' => COLLECTION_NAME, 'pipeline' => array( array('$match' => new stdClass), ), 'cursor' => array('batchSize' => 2), )); $cursor = $manager->executeCommand(DATABASE_NAME, $command); foreach ($cursor as $i => $document) { printf("%d => {_id: %d}\n", $i, $document->_id); } ?> ===DONE=== --EXPECT-- Inserted: 5 0 => {_id: 0} 1 => {_id: 1} 2 => {_id: 2} 3 => {_id: 3} 4 => {_id: 4} ===DONE=== mongodb-1.3.4/tests/cursor/cursor-getmore-005.phpt0000664000175000017500000000222713210321137021633 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor query result iteration with getmore failure --SKIPIF-- "30-release"]); CLEANUP(THROWAWAY); ?> --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $query = new MongoDB\Driver\Query([], ['batchSize' => 2]); $cursor = $manager->executeQuery(NS, $query); failGetMore($manager); throws(function() use ($cursor) { foreach ($cursor as $i => $document) { printf("%d => {_id: %d}\n", $i, $document->_id); } }, "MongoDB\Driver\Exception\ConnectionException"); ?> ===DONE=== --CLEAN-- --EXPECT-- Inserted: 5 0 => {_id: 0} 1 => {_id: 1} OK: Got MongoDB\Driver\Exception\ConnectionException ===DONE=== mongodb-1.3.4/tests/cursor/cursor-getmore-006.phpt0000664000175000017500000000244113210321137021632 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor command result iteration with getmore failure --SKIPIF-- "30-release"]); CLEANUP(THROWAWAY); ?> --FILE-- insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $command = new MongoDB\Driver\Command([ 'aggregate' => COLLECTION_NAME, 'pipeline' => [ ['$match' => new stdClass], ], 'cursor' => ['batchSize' => 2], ]); $cursor = $manager->executeCommand(DATABASE_NAME, $command); failGetMore($manager); throws(function() use ($cursor) { foreach ($cursor as $i => $document) { printf("%d => {_id: %d}\n", $i, $document->_id); } }, "MongoDB\Driver\Exception\ConnectionException"); ?> ===DONE=== --CLEAN-- --EXPECT-- Inserted: 5 0 => {_id: 0} 1 => {_id: 1} OK: Got MongoDB\Driver\Exception\ConnectionException ===DONE=== mongodb-1.3.4/tests/cursor/cursor-isDead-001.phpt0000664000175000017500000000136713210321137021362 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::isDead() with basic iteration (find command) --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); foreach ($cursor as $_) { var_dump($cursor->isDead()); } var_dump($cursor->isDead()); ?> ===DONE=== --EXPECT-- bool(false) bool(false) bool(false) bool(true) ===DONE=== mongodb-1.3.4/tests/cursor/cursor-isDead-002.phpt0000664000175000017500000000152313210321137021355 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::isDead() with IteratorIterator (find command) --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); $iterator = new IteratorIterator($cursor); $iterator->rewind(); for ($i = 0; $i < 3; $i++) { var_dump($cursor->isDead()); $iterator->next(); } var_dump($cursor->isDead()); ?> ===DONE=== --EXPECT-- bool(false) bool(false) bool(false) bool(true) ===DONE=== mongodb-1.3.4/tests/cursor/cursor-isDead-003.phpt0000664000175000017500000000137413210321137021362 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::isDead() with basic iteration (OP_QUERY) --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); foreach ($cursor as $_) { var_dump($cursor->isDead()); } var_dump($cursor->isDead()); ?> ===DONE=== --EXPECT-- bool(false) bool(false) bool(false) bool(true) ===DONE=== mongodb-1.3.4/tests/cursor/cursor-isDead-004.phpt0000664000175000017500000000153013210321137021355 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::isDead() with IteratorIterator (OP_QUERY) --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); $iterator = new IteratorIterator($cursor); $iterator->rewind(); for ($i = 0; $i < 3; $i++) { var_dump($cursor->isDead()); $iterator->next(); } var_dump($cursor->isDead()); ?> ===DONE=== --EXPECT-- bool(false) bool(false) bool(false) bool(true) ===DONE=== mongodb-1.3.4/tests/cursor/cursor-iterator_handlers-001.phpt0000664000175000017500000000401513210321137023673 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor iterator handlers --SKIPIF-- --FILE-- name = (string) $name; } public function dump() { $key = parent::key(); $current = parent::current(); $position = is_int($key) ? (string) $key : 'null'; $document = is_object($current) ? sprintf("{_id: %d}", $current->_id) : 'null'; printf("%s: %s => %s\n", $this->name, $position, $document); } } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulkWrite = new MongoDB\Driver\BulkWrite; for ($i = 0; $i < 5; $i++) { $bulkWrite->insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); $a = new MyIteratorIterator($cursor, 'A'); echo "\nBefore rewinding, position and current element are not populated:\n"; $a->dump(); echo "\nAfter rewinding, current element is populated:\n"; $a->rewind(); $a->dump(); echo "\nAfter advancing, next element is populated:\n"; $a->next(); $a->dump(); echo "\nAdvancing through remaining elements:\n"; $a->next(); $a->dump(); $a->next(); $a->dump(); $a->next(); $a->dump(); echo "\nAdvancing beyond the last element:\n"; $a->next(); $a->dump(); ?> ===DONE=== --EXPECT-- Inserted: 5 Before rewinding, position and current element are not populated: A: null => null After rewinding, current element is populated: A: 0 => {_id: 0} After advancing, next element is populated: A: 1 => {_id: 1} Advancing through remaining elements: A: 2 => {_id: 2} A: 3 => {_id: 3} A: 4 => {_id: 4} Advancing beyond the last element: A: null => null ===DONE=== mongodb-1.3.4/tests/cursor/cursor-rewind-001.phpt0000664000175000017500000000451613210321137021460 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor cannot rewind after starting iteration --SKIPIF-- --FILE-- name = (string) $name; } public function dump() { $key = parent::key(); $current = parent::current(); $position = is_int($key) ? (string) $key : 'null'; $document = is_object($current) ? sprintf("{_id: %d}", $current->_id) : 'null'; printf("%s: %s => %s\n", $this->name, $position, $document); } } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulkWrite = new MongoDB\Driver\BulkWrite; for ($i = 0; $i < 5; $i++) { $bulkWrite->insert(array('_id' => $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); $a = new MyIteratorIterator($cursor, 'A'); echo "\nRewinding sets the current element:\n"; $a->rewind(); $a->dump(); echo "\nRewinding again is OK since we haven't advanced:\n"; $a->rewind(); $a->dump(); echo "\nAdvancing populates the next element:\n"; $a->next(); $a->dump(); echo "\nRewinding after advancing is not OK:\n"; try { $a->rewind(); echo "FAILED: rewind should throw if iteration has started\n"; } catch (MongoDB\Driver\Exception\LogicException $e) { printf("LogicException: %s\n", $e->getMessage()); } echo "\nAdvancing through remaining elements:\n"; $a->next(); $a->dump(); $a->next(); $a->dump(); $a->next(); $a->dump(); echo "\nAdvancing beyond the last element:\n"; $a->next(); $a->dump(); ?> ===DONE=== --EXPECT-- Inserted: 5 Rewinding sets the current element: A: 0 => {_id: 0} Rewinding again is OK since we haven't advanced: A: 0 => {_id: 0} Advancing populates the next element: A: 1 => {_id: 1} Rewinding after advancing is not OK: LogicException: Cursors cannot rewind after starting iteration Advancing through remaining elements: A: 2 => {_id: 2} A: 3 => {_id: 3} A: 4 => {_id: 4} Advancing beyond the last element: A: null => null ===DONE=== mongodb-1.3.4/tests/cursor/cursor-setTypeMap_error-001.phpt0000664000175000017500000000557013210321137023475 0ustar jmikolajmikola--TEST-- Cursor::setTypeMap(): Type classes must be instantiatable and implement Unserializable --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query([])); foreach ($types as $type) { foreach ($classes as $class) { $typeMap = [$type => $class]; printf("Test typeMap: %s\n", json_encode($typeMap)); echo throws(function() use ($cursor, $typeMap) { $cursor->setTypeMap($typeMap); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo "\n"; } } ?> ===DONE=== --EXPECT-- Test typeMap: {"array":"MissingClass"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist Test typeMap: {"array":"MyAbstractDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyAbstractDocument is not instantiatable Test typeMap: {"array":"MyDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyDocument does not implement MongoDB\BSON\Unserializable Test typeMap: {"array":"MongoDB\\BSON\\Unserializable"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MongoDB\BSON\Unserializable is not instantiatable Test typeMap: {"document":"MissingClass"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist Test typeMap: {"document":"MyAbstractDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyAbstractDocument is not instantiatable Test typeMap: {"document":"MyDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyDocument does not implement MongoDB\BSON\Unserializable Test typeMap: {"document":"MongoDB\\BSON\\Unserializable"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MongoDB\BSON\Unserializable is not instantiatable Test typeMap: {"root":"MissingClass"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist Test typeMap: {"root":"MyAbstractDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyAbstractDocument is not instantiatable Test typeMap: {"root":"MyDocument"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MyDocument does not implement MongoDB\BSON\Unserializable Test typeMap: {"root":"MongoDB\\BSON\\Unserializable"} OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MongoDB\BSON\Unserializable is not instantiatable ===DONE=== mongodb-1.3.4/tests/cursor/cursor-setTypeMap_error-002.phpt0000664000175000017500000000232413210321137023470 0ustar jmikolajmikola--TEST-- Cursor::setTypeMap() error does not alter current element --SKIPIF-- --FILE-- insert(['_id' => 1]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); $iterator = new IteratorIterator($cursor); $iterator->rewind(); var_dump($iterator->current()); echo throws(function() use ($cursor) { $cursor->setTypeMap(['root' => 'MissingClass']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; /* IteratorIterator only invokes spl_dual_it_fetch() for rewind() and next(). * We rewind a second time to ensure that the Cursor iterator's current element * is fetched again is remains unchanged. */ $iterator->rewind(); var_dump($iterator->current()); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["_id"]=> int(1) } OK: Got MongoDB\Driver\Exception\InvalidArgumentException Class MissingClass does not exist object(stdClass)#%d (%d) { ["_id"]=> int(1) } ===DONE=== mongodb-1.3.4/tests/cursor/cursor-tailable-001.phpt0000664000175000017500000000351513210321137021743 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor tailable iteration --SKIPIF-- --FILE-- insert(['_id' => $i]); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted %d document(s): %s\n", $writeResult->getInsertedCount(), implode(range($from, $to), ', ')); } $manager = new MongoDB\Driver\Manager(STANDALONE); $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'create' => COLLECTION_NAME, 'capped' => true, 'size' => 1048576, ])); insert($manager, 1, 3); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['tailable' => true])); $it = new IteratorIterator($cursor); $numAwaitAttempts = 0; $maxAwaitAttempts = 7; for ($it->rewind(); $numAwaitAttempts < $maxAwaitAttempts; $it->next()) { $document = $it->current(); if ($document !== null) { printf("{_id: %d}\n", $document->_id); continue; } if ($numAwaitAttempts === 2) { insert($manager, 4, 6); } if ($numAwaitAttempts === 5) { insert($manager, 7, 9); } echo "Awaiting results...\n"; $numAwaitAttempts += 1; } ?> ===DONE=== --EXPECT-- Inserted 3 document(s): 1, 2, 3 {_id: 1} {_id: 2} {_id: 3} Awaiting results... Awaiting results... Inserted 3 document(s): 4, 5, 6 Awaiting results... {_id: 4} {_id: 5} {_id: 6} Awaiting results... Awaiting results... Inserted 3 document(s): 7, 8, 9 Awaiting results... {_id: 7} {_id: 8} {_id: 9} Awaiting results... ===DONE=== mongodb-1.3.4/tests/cursor/cursor-tailable-002.phpt0000664000175000017500000000360013210321137021737 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor tailable iteration with awaitData option --SKIPIF-- --FILE-- insert(['_id' => $i]); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted %d document(s): %s\n", $writeResult->getInsertedCount(), implode(range($from, $to), ', ')); } $manager = new MongoDB\Driver\Manager(STANDALONE); $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'create' => COLLECTION_NAME, 'capped' => true, 'size' => 1048576, ])); insert($manager, 1, 3); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['tailable' => true, 'awaitData' => true])); $it = new IteratorIterator($cursor); $numAwaitAttempts = 0; $maxAwaitAttempts = 7; for ($it->rewind(); $numAwaitAttempts < $maxAwaitAttempts; $it->next()) { $document = $it->current(); if ($document !== null) { printf("{_id: %d}\n", $document->_id); continue; } if ($numAwaitAttempts === 2) { insert($manager, 4, 6); } if ($numAwaitAttempts === 5) { insert($manager, 7, 9); } echo "Awaiting results...\n"; $numAwaitAttempts += 1; } ?> ===DONE=== --EXPECT-- Inserted 3 document(s): 1, 2, 3 {_id: 1} {_id: 2} {_id: 3} Awaiting results... Awaiting results... Inserted 3 document(s): 4, 5, 6 Awaiting results... {_id: 4} {_id: 5} {_id: 6} Awaiting results... Awaiting results... Inserted 3 document(s): 7, 8, 9 Awaiting results... {_id: 7} {_id: 8} {_id: 9} Awaiting results... ===DONE=== mongodb-1.3.4/tests/cursor/cursor-tailable-003.phpt0000664000175000017500000000213013210321137021735 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor tailable iteration with awaitData and maxAwaitTimeMS options --SKIPIF-- --FILE-- executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'create' => COLLECTION_NAME, 'capped' => true, 'size' => 1048576, ])); $bulkWrite = new MongoDB\Driver\BulkWrite; $bulkWrite->insert(['_id' => 1]); $manager->executeBulkWrite(NS, $bulkWrite); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], [ 'tailable' => true, 'awaitData' => true, 'maxAwaitTimeMS' => 10, ])); $it = new IteratorIterator($cursor); $it->rewind(); printf("{_id: %d}\n", $it->current()->_id); $it->next(); $startTime = microtime(true); echo "Awaiting results...\n"; $it->next(); printf("Waited for %.6f seconds\n", microtime(true) - $startTime); ?> ===DONE=== --EXPECTF-- {_id: 1} Awaiting results... Waited for 0.01%d seconds ===DONE=== mongodb-1.3.4/tests/cursor/cursor-tailable_error-001.phpt0000664000175000017500000000415013210321137023150 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor collection dropped during tailable iteration --SKIPIF-- --FILE-- insert(['_id' => $i]); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted %d document(s): %s\n", $writeResult->getInsertedCount(), implode(range($from, $to), ', ')); } $manager = new MongoDB\Driver\Manager(STANDALONE); $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'create' => COLLECTION_NAME, 'capped' => true, 'size' => 1048576, ])); insert($manager, 1, 3); echo throws(function() use ($manager) { $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['tailable' => true])); $it = new IteratorIterator($cursor); $numAwaitAttempts = 0; $maxAwaitAttempts = 7; for ($it->rewind(); $numAwaitAttempts < $maxAwaitAttempts; $it->next()) { $document = $it->current(); if ($document !== null) { printf("{_id: %d}\n", $document->_id); continue; } if ($numAwaitAttempts === 2) { insert($manager, 4, 6); } if ($numAwaitAttempts === 5) { $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['drop' => COLLECTION_NAME])); } echo "Awaiting results...\n"; $numAwaitAttempts += 1; } }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; ?> ===DONE=== --EXPECT-- Inserted 3 document(s): 1, 2, 3 {_id: 1} {_id: 2} {_id: 3} Awaiting results... Awaiting results... Inserted 3 document(s): 4, 5, 6 Awaiting results... {_id: 4} {_id: 5} {_id: 6} Awaiting results... Awaiting results... Awaiting results... OK: Got MongoDB\Driver\Exception\RuntimeException collection dropped between getMore calls ===DONE=== mongodb-1.3.4/tests/cursor/cursor-tailable_error-002.phpt0000664000175000017500000000426413210321137023157 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor cursor killed during tailable iteration --SKIPIF-- --FILE-- insert(['_id' => $i]); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted %d document(s): %s\n", $writeResult->getInsertedCount(), implode(range($from, $to), ', ')); } $manager = new MongoDB\Driver\Manager(STANDALONE); $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'create' => COLLECTION_NAME, 'capped' => true, 'size' => 1048576, ])); insert($manager, 1, 3); echo throws(function() use ($manager) { $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['tailable' => true])); $it = new IteratorIterator($cursor); $numAwaitAttempts = 0; $maxAwaitAttempts = 7; for ($it->rewind(); $numAwaitAttempts < $maxAwaitAttempts; $it->next()) { $document = $it->current(); if ($document !== null) { printf("{_id: %d}\n", $document->_id); continue; } if ($numAwaitAttempts === 2) { insert($manager, 4, 6); } if ($numAwaitAttempts === 5) { $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command([ 'killCursors' => COLLECTION_NAME, 'cursors' => [ $cursor->getId() ], ])); } echo "Awaiting results...\n"; $numAwaitAttempts += 1; } }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; ?> ===DONE=== --EXPECTF-- Inserted 3 document(s): 1, 2, 3 {_id: 1} {_id: 2} {_id: 3} Awaiting results... Awaiting results... Inserted 3 document(s): 4, 5, 6 Awaiting results... {_id: 4} {_id: 5} {_id: 6} Awaiting results... Awaiting results... Awaiting results... OK: Got MongoDB\Driver\Exception\RuntimeException Cursor not found, cursor id: %d ===DONE=== mongodb-1.3.4/tests/cursor/cursor-toArray-001.phpt0000664000175000017500000000242713210321137021610 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::toArray() --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1))); echo "Dumping Cursor::toArray():\n"; var_dump($cursor->toArray()); // Execute the query a second time, since we cannot iterate twice $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1))); echo "\nDumping iterated Cursor:\n"; var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- Dumping Cursor::toArray(): array(2) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(1) } } Dumping iterated Cursor: array(2) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(1) } } ===DONE=== mongodb-1.3.4/tests/cursor/cursor-toArray-002.phpt0000664000175000017500000000167113210321137021611 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::toArray() respects type map --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => array(1, 2, 3))); $bulk->insert(array('_id' => 2, 'x' => array(4, 5, 6))); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array('x' => 1))); $cursor->setTypeMap(array("array" => "MyArrayObject")); $documents = $cursor->toArray(); var_dump($documents[0]->x instanceof MyArrayObject); ?> ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/cursor/cursor_error-001.phpt0000664000175000017500000000040513210321137021374 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyCursor may not inherit from final class (MongoDB\Driver\Cursor) in %s on line %d mongodb-1.3.4/tests/cursorid/cursorid-001.phpt0000664000175000017500000000144513210321137021022 0ustar jmikolajmikola--TEST-- MongoDB\Driver\CursorID BSON serialization --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); $cursorId = $cursor->getId(); hex_dump(fromPHP(['cid' => $cursorId])); ?> ===DONE=== --EXPECTF-- 0 : 12 00 00 00 12 63 69 64 00 %x %x %x %x %x %x %x [.....cid.%s] 10 : %x 00 [%s.] ===DONE=== mongodb-1.3.4/tests/cursorid/cursorid-002.phpt0000664000175000017500000000241113210321137021015 0ustar jmikolajmikola--TEST-- MongoDB\Driver\CursorID BSON serialization for killCursors command --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([], ['batchSize' => 2])); $cursorId = $cursor->getId(); $command = new MongoDB\Driver\Command([ 'killCursors' => COLLECTION_NAME, 'cursors' => [ $cursorId ], ]); /* Since the killCursors command result includes cursor IDs as 64-bit integers, * unserializing the result document requires a 64-bit platform. */ $result = $manager->executeCommand(DATABASE_NAME, $command)->toArray()[0]; printf("Killed %d cursor(s)\n", count($result->cursorsKilled)); printf("Killed expected cursor: %s\n", (string) $cursorId === (string) $result->cursorsKilled[0] ? 'yes' : 'no'); ?> ===DONE=== --EXPECT-- Killed 1 cursor(s) Killed expected cursor: yes ===DONE=== mongodb-1.3.4/tests/cursorid/cursorid_error-001.phpt0000664000175000017500000000041713210321137022231 0ustar jmikolajmikola--TEST-- MongoDB\Driver\CursorId cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyCursorId may not inherit from final class (MongoDB\Driver\CursorId) in %s on line %d mongodb-1.3.4/tests/functional/cursor-001.phpt0000664000175000017500000000357513210321137021023 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.3.4/tests/functional/cursorid-001.phpt0000664000175000017500000000151413210321137021327 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"]=> %rint\(\d+\)|string\(\d+\) "\d+"%r } string(%d) "%d" bool(true) ===DONE=== mongodb-1.3.4/tests/functional/phpinfo-1.phpt0000664000175000017500000000043113210321137020775 0ustar jmikolajmikola--TEST-- phpinfo() reports mongodb.debug (no value) --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- %a mongodb.debug => no value => no value %a ===DONE=== mongodb-1.3.4/tests/functional/phpinfo-2.phpt0000664000175000017500000000054413210321137021003 0ustar jmikolajmikola--TEST-- phpinfo() reports mongodb.debug (default and overridden) --INI-- mongodb.debug=stderr --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- %a mongodb.debug => stdout => stderr %a ===DONE=== mongodb-1.3.4/tests/functional/query-sort-001.phpt0000664000175000017500000000346213210321137021633 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.3.4/tests/functional/query-sort-002.phpt0000664000175000017500000000322613210321137021632 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.3.4/tests/functional/query-sort-003.phpt0000664000175000017500000003134013210321137021631 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) { ["filter"]=> object(stdClass)#%d (%d) { } ["options"]=> object(stdClass)#%d (%d) { ["projection"]=> object(stdClass)#%d (%d) { ["_id"]=> int(0) ["username"]=> int(1) } ["sort"]=> object(stdClass)#%d (%d) { ["username"]=> int(1) } } ["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.3.4/tests/functional/query-sort-004.phpt0000664000175000017500000000237413210321137021637 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) { ["filter"]=> object(stdClass)#%d (%d) { } ["options"]=> object(stdClass)#%d (%d) { ["sort"]=> object(stdClass)#%d (%d) { [%r(0|"0")%r]=> int(1) } } ["readConcern"]=> NULL } 0 1 2 3 4 ===DONE=== mongodb-1.3.4/tests/manager/bug0572.phpt0000664000175000017500000000147213210321137017545 0ustar jmikolajmikola--TEST-- PHPC-572: Ensure stream context does not go out of scope before socket init --SKIPIF-- --FILE-- [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true, ], ]); return new MongoDB\Driver\Manager(STANDALONE_SSL, ['ssl' => true], ['context' => $context]); }; $manager = $closure(); $cursor = $manager->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/manager/bug0851-001.phpt0000664000175000017500000000175013210321137020042 0ustar jmikolajmikola--TEST-- PHPC-851: Manager constructor should not modify options argument --FILE-- 'secondaryPreferred', 'readPreferenceTags' => [ ['dc' => 'ny'], [], ], ]; $manager = new MongoDB\Driver\Manager(null, $options); var_dump($options); /* Dump the Manager's ReadPreference to ensure that each element in the * readPreferenceTags option was converted to an object. */ var_dump($manager->getReadPreference()); ?> ===DONE=== --EXPECTF-- array(2) { ["readPreference"]=> string(18) "secondaryPreferred" ["readPreferenceTags"]=> array(2) { [0]=> array(1) { ["dc"]=> string(2) "ny" } [1]=> array(0) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" ["tags"]=> array(2) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" } [1]=> object(stdClass)#%d (%d) { } } } ===DONE=== mongodb-1.3.4/tests/manager/bug0851-002.phpt0000664000175000017500000000102313210321137020034 0ustar jmikolajmikola--TEST-- PHPC-851: Manager constructor should not modify driverOptions argument --FILE-- true, 'context' => stream_context_create([ 'ssl' => [ 'allow_self_signed' => true, ], ]), ]; $manager = new MongoDB\Driver\Manager(null, [], $driverOptions); var_dump($driverOptions); ?> ===DONE=== --EXPECT-- array(2) { ["weak_cert_validation"]=> bool(true) ["context"]=> resource(4) of type (stream-context) } ===DONE=== mongodb-1.3.4/tests/manager/bug0912-001.phpt0000664000175000017500000000317113210321137020037 0ustar jmikolajmikola--TEST-- PHPC-912: Child process should not destroy mongoc_client_t objects from parent --SKIPIF-- --FILE-- 1]); $cursor = $manager->executeCommand(DATABASE_NAME, $command); $uri = $cursor->toArray()[0]->you; $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['pid' => getmypid(), 'uri' => $uri]); $manager->executeBulkWrite(NS, $bulk); } $manager = new MongoDB\Driver\Manager(STANDALONE); logMyURI($manager); $parentPid = getmypid(); $childPid = pcntl_fork(); if ($childPid === 0) { $manager = new MongoDB\Driver\Manager(STANDALONE); logMyURI($manager); exit; } if ($childPid) { $waitPid = pcntl_waitpid($childPid, $status); if ($waitPid > 0) { printf("Parent(%d) waited for child(%d) to exit\n", $parentPid, $waitPid); } $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); $results = $cursor->toArray(); printf("%d connections were logged\n", count($results)); printf("PIDs differ: %s\n", $results[0]->pid !== $results[1]->pid ? 'yes' : 'no'); printf("URIs differ: %s\n", $results[0]->uri !== $results[1]->uri ? 'yes' : 'no'); } ?> ===DONE=== --EXPECTF-- Parent(%d) waited for child(%d) to exit 2 connections were logged PIDs differ: yes URIs differ: yes ===DONE=== mongodb-1.3.4/tests/manager/bug0913-001.phpt0000664000175000017500000000413313210321137020037 0ustar jmikolajmikola--TEST-- PHPC-913: Child process should not re-use mongoc_client_t objects from parent --SKIPIF-- --FILE-- 1]); $cursor = $manager->executeCommand(DATABASE_NAME, $command); $uri = $cursor->toArray()[0]->you; $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['pid' => getmypid(), 'uri' => $uri]); $manager->executeBulkWrite(NS, $bulk); } $manager = new MongoDB\Driver\Manager(STANDALONE); logMyURI($manager); $parentPid = getmypid(); $childPid = pcntl_fork(); if ($childPid === 0) { $manager = new MongoDB\Driver\Manager(STANDALONE); logMyURI($manager); /* Due to PHPC-912, we cannot allow the child process to terminate before * the parent is done using its client, lest it destroy the mongoc_client_t * object and shutdown its socket(s). Sleep for 250ms to allow the parent * time to query for our logged URI. */ usleep(250000); exit; } if ($childPid) { /* Sleep for 100ms to allow the child time to log its URI. Ideally, we would * wait for the child to finish, but PHPC-912 prevents us from doing so. */ usleep(100000); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); $results = $cursor->toArray(); printf("%d connections were logged\n", count($results)); printf("PIDs differ: %s\n", $results[0]->pid !== $results[1]->pid ? 'yes' : 'no'); printf("URIs differ: %s\n", $results[0]->uri !== $results[1]->uri ? 'yes' : 'no'); $waitPid = pcntl_waitpid($childPid, $status); if ($waitPid > 0) { printf("Parent(%d) waited for child(%d) to exit\n", $parentPid, $waitPid); } } ?> ===DONE=== --EXPECTF-- 2 connections were logged PIDs differ: yes URIs differ: yes Parent(%d) waited for child(%d) to exit ===DONE=== mongodb-1.3.4/tests/manager/bug0940-001.phpt0000664000175000017500000000063513210321137020042 0ustar jmikolajmikola--TEST-- PHPC-940: php_phongo_free_ssl_opt() attempts to free interned strings --SKIPIF-- --FILE-- false])); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Manager)#%d (%d) { ["uri"]=> string(20) "mongodb://127.0.0.1/" ["cluster"]=> array(0) { } } ===DONE=== mongodb-1.3.4/tests/manager/bug0940-002.phpt0000664000175000017500000000076513210321137020047 0ustar jmikolajmikola--TEST-- PHPC-940: php_phongo_free_ssl_opt() attempts to free interned strings (context option) --SKIPIF-- --FILE-- ['cafile' => false]]); var_dump(new MongoDB\Driver\Manager(null, [], ['context' => $context])); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Manager)#%d (%d) { ["uri"]=> string(20) "mongodb://127.0.0.1/" ["cluster"]=> array(0) { } } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-001.phpt0000664000175000017500000000026013210321137021321 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct() with default URI --FILE-- ===DONE=== --EXPECT-- ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-002.phpt0000664000175000017500000000052713210321137021330 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct() with URI --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-003.phpt0000664000175000017500000000072613210321137021332 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct() URI defaults to "mongodb://127.0.0.1/" --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- [%s] PHONGO: DEBUG > Connection string: 'mongodb://127.0.0.1/' %A ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-004.phpt0000664000175000017500000000116313210321137021327 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): Deprecated boolean options in URI string --FILE-- getWriteConcern()->getJournal()); } ?> ===DONE=== --EXPECTF-- bool(true) bool(true) bool(true) bool(true) bool(false) bool(false) bool(false) bool(false) bool(false) ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-appname-001.phpt0000664000175000017500000000105313210321137022741 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): appname option --SKIPIF-- --FILE-- "2-{$name2}"]); $command = new MongoDB\Driver\Command(['ping' => 1]); $manager->executeCommand("test", $command); ?> ===DONE=== --EXPECT-- ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-appname_error-001.phpt0000664000175000017500000000332613210321137024157 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid appname --FILE-- "2-{$name2}"]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid appname value: '2-PHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGOPHONGO' ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-auth_mechanism-001.phpt0000664000175000017500000000117013210321137024305 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): authMechanism option --FILE-- 'MONGODB-X509']], [null, ['authMechanism' => 'GSSAPI']], ]; foreach ($tests as $test) { list($uri, $options) = $test; /* Note: the Manager's debug information does not include the auth mechanism * so we are merely testing that no exception is thrown. */ $manager = new MongoDB\Driver\Manager($uri, $options); } ?> ===DONE=== --EXPECT-- ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-auth_mechanism-002.phpt0000664000175000017500000000244113210321137024310 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): authMechanismProperties option --FILE-- 'GSSAPI', 'authMechanismProperties' => ['CANONICALIZE_HOST_NAME' => 'true', 'SERVICE_NAME' => 'foo', 'SERVICE_REALM' => 'bar']]], // Options are case-insensitive ['mongodb://127.0.0.1/?authMechanism=GSSAPI&authMechanismProperties=canonicalize_host_name:TRUE,service_name:foo,service_realm:bar', []], [null, ['authMechanism' => 'GSSAPI', 'authMechanismProperties' => ['canonicalize_host_name' => 'TRUE', 'service_name' => 'foo', 'service_realm' => 'bar']]], // Boolean true "CANONICALIZE_HOST_NAME" value is converted to "true" [null, ['authMechanism' => 'GSSAPI', 'authMechanismProperties' => ['canonicalize_host_name' => true]]], ]; foreach ($tests as $test) { list($uri, $options) = $test; /* Note: the Manager's debug information does not include the auth mechanism * so we are merely testing that no exception is thrown and that option * processing does not leak memory. */ $manager = new MongoDB\Driver\Manager($uri, $options); } ?> ===DONE=== --EXPECT-- ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_concern-001.phpt0000664000175000017500000000143513210321137023746 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): read concern options --FILE-- 'local']], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getReadConcern()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(5) "local" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(1) "1" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(5) "local" } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_concern-error-001.phpt0000664000175000017500000000072713210321137025100 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid read concern --FILE-- 1]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "readConcernLevel" URI option, 32-bit integer given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_preference-001.phpt0000664000175000017500000000326313210321137024436 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): read preference options --FILE-- 'primary']], [null, ['readPreference' => 'secondary', 'readPreferenceTags' => [['tag' => 'one'], []]]], [null, ['readPreference' => 'secondary', 'maxStalenessSeconds' => 1000]], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getReadPreference()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(2) { [0]=> object(stdClass)#%d (%d) { ["tag"]=> string(3) "one" } [1]=> object(stdClass)#%d (%d) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1000) } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(2) { [0]=> object(stdClass)#%d (%d) { ["tag"]=> string(3) "one" } [1]=> object(stdClass)#%d (%d) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_preference-002.phpt0000664000175000017500000000262013210321137024433 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): read preference options (maxStalenessSeconds) --FILE-- 1231]], ['mongodb://127.0.0.1/?readPreference=secondary&maxStalenessSeconds=1000', ['maxStalenessSeconds' => 2000]], ['mongodb://127.0.0.1/?readpreference=secondary&maxstalenessseconds=1231', []], ['mongodb://127.0.0.1/?readpreference=secondary', ['maxstalenessseconds' => 1231]], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getReadPreference()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1231) } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1231) } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(2000) } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1231) } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1231) } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_preference-004.phpt0000664000175000017500000000635613210321137024447 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): read preference options (slaveok) --FILE-- true]], ['mongodb://127.0.0.1/?readPreference=nearest', ['slaveok' => true]], // False array option is ignored ['mongodb://127.0.0.1/?slaveok=true', ['slaveok' => false]], ['mongodb://127.0.0.1/?readPreference=nearest', ['slaveok' => false]], // readPreference option takes priority ['mongodb://127.0.0.1/?slaveok=true&readPreference=nearest', []], ['mongodb://127.0.0.1/?slaveok=false&readPreference=nearest', []], ['mongodb://127.0.0.1/?slaveok=true', ['readPreference' => 'nearest']], ['mongodb://127.0.0.1/?slaveok=false', ['readPreference' => 'nearest']], [null, ['readPreference' => 'nearest', 'slaveok' => true]], [null, ['readPreference' => 'nearest', 'slaveok' => true]], // Alternative values for true in URI string (all other strings are false) ['mongodb://127.0.0.1/?slaveok=t', []], ['mongodb://127.0.0.1/?slaveok=1', []], // Case insensitivity for URI string and array options ['mongodb://127.0.0.1/?slaveOk=True', []], ['mongodb://127.0.0.1/?SLAVEOK=TRUE', []], [null, ['slaveOk' => true]], [null, ['SLAVEOK' => true]], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getReadPreference()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_preference-error-001.phpt0000664000175000017500000000556213210321137025571 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid read preference (mode and tags) --FILE-- 1]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['readPreference' => 'primary', 'readPreferenceTags' => 'invalid']); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; // Invalid values echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?readPreference=primary&readPreferenceTags=dc:ny'); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['readPreference' => 'nothing']); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?readPreference=primary', ['readPreferenceTags' => [[]]]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?readPreference=primary', ['readPreferenceTags' => ['invalid']]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?readPreference=1'. Unsupported readPreference value [readPreference=1].. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?readPreference=secondary&readPreferenceTags=invalid'. Unknown option or value for 'readPreferenceTags=invalid'. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "readPreference" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected array for "readPreferenceTags" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?readPreference=primary&readPreferenceTags=dc:ny'. Invalid readPreferences. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Unsupported readPreference value: 'nothing' OK: Got MongoDB\Driver\Exception\InvalidArgumentException Primary read preference mode conflicts with tags OK: Got MongoDB\Driver\Exception\InvalidArgumentException Read preference tags must be an array of zero or more documents ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_preference-error-002.phpt0000664000175000017500000000701013210321137025560 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid read preference (maxStalenessSeconds) --FILE-- 'invalid']); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; // Invalid range in URI string (array option is tested in 64-bit error test) echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?readPreference=secondary&maxStalenessSeconds=2147483648'); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; // Invalid values echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?maxstalenessseconds=1231'); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?maxStalenessSeconds=1231'); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['maxstalenessseconds' => 1231]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['maxStalenessSeconds' => 1231]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['readPreference' => 'secondary', 'maxStalenessSeconds' => -2]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['readPreference' => 'secondary', 'maxStalenessSeconds' => 0]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['readPreference' => 'secondary', 'maxStalenessSeconds' => 42]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?readPreference=secondary&maxStalenessSeconds=invalid'. Unknown option or value for 'maxStalenessSeconds=invalid'. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected integer for "maxStalenessSeconds" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?readPreference=secondary&maxStalenessSeconds=2147483648'. Unknown option or value for 'maxStalenessSeconds=2147483648'. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?maxstalenessseconds=1231'. Invalid readPreferences. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?maxStalenessSeconds=1231'. Invalid readPreferences. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Primary read preference mode conflicts with maxStalenessSeconds OK: Got MongoDB\Driver\Exception\InvalidArgumentException Primary read preference mode conflicts with maxStalenessSeconds OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be >= 90, -2 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be >= 90, 0 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be >= 90, 42 given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_preference-error-003.phpt0000664000175000017500000000143313210321137025564 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid read preference (slaveOk) --FILE-- 1]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?slaveok=other'. Unknown option or value for 'slaveok=other'. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected boolean for "slaveOk" URI option, 32-bit integer given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-read_preference-error-004.phpt0000664000175000017500000000116313210321137025565 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid read preference (maxStalenessSeconds range) --SKIPIF-- --FILE-- 'secondary', 'maxStalenessSeconds' => 2147483648]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be <= 2147483647, 2147483648 given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-ssl-001.phpt0000664000175000017500000000147413210321137022130 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): ssl option does not require driverOptions --FILE-- true])); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Manager)#%d (%d) { ["uri"]=> string(29) "mongodb://127.0.0.1/?ssl=true" ["cluster"]=> array(0) { } } object(MongoDB\Driver\Manager)#%d (%d) { ["uri"]=> string(20) "mongodb://127.0.0.1/" ["cluster"]=> array(0) { } } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-001.phpt0000664000175000017500000000261313210321137024164 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): write concern options (w) --FILE-- -1]], [null, ['w' => -0]], [null, ['w' => 1]], [null, ['w' => 'majority']], [null, ['w' => 'customTagSet']], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getWriteConcern()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(-1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(12) "customTagSet" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(-1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(12) "customTagSet" } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-002.phpt0000664000175000017500000000306513210321137024167 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): write concern options (wtimeoutms) --FILE-- 1, w = majority, or tag sets are used ['mongodb://127.0.0.1/?wtimeoutms=1000', []], ['mongodb://127.0.0.1/?w=2&wtimeoutms=1000', []], ['mongodb://127.0.0.1/?w=majority&wtimeoutms=1000', []], ['mongodb://127.0.0.1/?w=customTagSet&wtimeoutms=1000', []], [null, ['wtimeoutms' => 1000]], [null, ['w' => 2, 'wtimeoutms' => 1000]], [null, ['w' => 'majority', 'wtimeoutms' => 1000]], [null, ['w' => 'customTagSet', 'wtimeoutms' => 1000]], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getWriteConcern()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(12) "customTagSet" ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(12) "customTagSet" ["wtimeout"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-003.phpt0000664000175000017500000000141613210321137024166 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): write concern options (journal) --FILE-- true]], [null, ['journal' => false]], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getWriteConcern()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["j"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["j"]=> bool(false) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["j"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["j"]=> bool(false) } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-004.phpt0000664000175000017500000000301713210321137024166 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): write concern options (safe) --FILE-- true]], [null, ['safe' => false]], [null, ['w' => 1, 'safe' => false]], [null, ['w' => 0, 'safe' => true]], // safe in URI options array may override w in URI string ['mongodb://127.0.0.1/?w=0', ['safe' => true]], ['mongodb://127.0.0.1/?w=1', ['safe' => false]], ]; foreach ($tests as $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getWriteConcern()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-error-001.phpt0000664000175000017500000000177513210321137025323 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid write concern (w) --FILE-- 1.0]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; /* Note: Values of w < -1 are invalid, but libmongoc's URI string parsing only * logs a warning instead of raising an error (see: CDRIVER-2234), so we cannot * test for this. */ echo throws(function() { new MongoDB\Driver\Manager(null, ['w' => -2]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer or string for "w" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Unsupported w value: -2 ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-error-002.phpt0000664000175000017500000000125013210321137025310 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid write concern (w range) --SKIPIF-- --FILE-- 2147483648]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer or string for "w" URI option, 64-bit integer given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-error-003.phpt0000664000175000017500000000147113210321137025316 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid write concern (wtimeoutms) --FILE-- 'invalid']); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?wtimeoutms=invalid'. Unknown option or value for 'wtimeoutms=invalid'. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "wTimeoutMS" URI option, string given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-error-004.phpt0000664000175000017500000000130213210321137025310 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid write concern (wtimeoutms range) --SKIPIF-- --FILE-- 2147483648]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "wTimeoutMS" URI option, 64-bit integer given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-error-005.phpt0000664000175000017500000000577713210321137025335 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid write concern (journal) --FILE-- 'invalid']); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; // Invalid values (journal conflicts with unacknowledged write concerns) echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=-1&journal=true'); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=0&journal=true'); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=-1', ['journal' => true]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=0', ['journal' => true]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?journal=true', ['w' => -1]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager('mongodb://127.0.0.1/?journal=true', ['w' => 0]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['w' => -1, 'journal' => true]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { new MongoDB\Driver\Manager(null, ['w' => 0, 'journal' => true]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?journal=invalid'. Unknown option or value for 'journal=invalid'. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected boolean for "journal" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?w=-1&journal=true'. Invalid writeConcern. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?w=0&journal=true'. Invalid writeConcern. 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 ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor-write_concern-error-006.phpt0000664000175000017500000000143713210321137025323 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid write concern (safe) --FILE-- 'invalid']); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'mongodb://127.0.0.1/?safe=invalid'. Unknown option or value for 'safe=invalid'. OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected boolean for "safe" URI option, string given ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor_error-001.phpt0000664000175000017500000000111713210321137022534 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.3.4/tests/manager/manager-ctor_error-002.phpt0000664000175000017500000000077213210321137022543 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid URI --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'not a valid connection string'. Invalid URI Schema, expecting 'mongodb://'. ===DONE=== mongodb-1.3.4/tests/manager/manager-ctor_error-003.phpt0000664000175000017500000003100113210321137022531 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid types in URI options arrays --FILE-- 1], ]; foreach ($integerOptions as $option) { foreach ($invalidIntegerValues as $value) { echo throws(function() use ($option, $value) { new MongoDB\Driver\Manager(null, [$option => $value]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; } } echo "\nTesting string options:\n"; $stringOptions = [ 'appname', 'authMechanism', 'authSource', 'gssapiServiceName', 'password', 'replicaSet', 'username', ]; $invalidStringValues = [ true, 1.0, 42, new MongoDB\BSON\ObjectId, [ 1, 2, 3 ], ['x' => 1], ]; foreach ($stringOptions as $option) { foreach ($invalidStringValues as $value) { echo throws(function() use ($option, $value) { new MongoDB\Driver\Manager(null, [$option => $value]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; } } echo "\nTesting document options:\n"; $invalidDocumentValues = [ true, 1.0, 42, 'string', new MongoDB\BSON\ObjectId, [ 1, 2, 3 ], ]; foreach ($invalidDocumentValues as $value) { echo throws(function() use ($value) { new MongoDB\Driver\Manager(null, ['authMechanismProperties' => $value]); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; } ?> ===DONE=== --EXPECT-- Testing 32-bit integer options: OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "connectTimeoutMS" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "connectTimeoutMS" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "connectTimeoutMS" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "connectTimeoutMS" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "connectTimeoutMS" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "connectTimeoutMS" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "heartbeatFrequencyMS" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "heartbeatFrequencyMS" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "heartbeatFrequencyMS" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "heartbeatFrequencyMS" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "heartbeatFrequencyMS" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "heartbeatFrequencyMS" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "localThresholdMS" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "localThresholdMS" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "localThresholdMS" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "localThresholdMS" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "localThresholdMS" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "localThresholdMS" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "serverSelectionTimeoutMS" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "serverSelectionTimeoutMS" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "serverSelectionTimeoutMS" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "serverSelectionTimeoutMS" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "serverSelectionTimeoutMS" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "serverSelectionTimeoutMS" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketCheckIntervalMS" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketCheckIntervalMS" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketCheckIntervalMS" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketCheckIntervalMS" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketCheckIntervalMS" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketCheckIntervalMS" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketTimeoutMS" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketTimeoutMS" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketTimeoutMS" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketTimeoutMS" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketTimeoutMS" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected 32-bit integer for "socketTimeoutMS" URI option, document given Testing string options: OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "appname" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "appname" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "appname" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "appname" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "appname" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "appname" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authMechanism" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authMechanism" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authMechanism" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authMechanism" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authMechanism" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authMechanism" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authSource" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authSource" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authSource" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authSource" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authSource" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "authSource" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "gssapiServiceName" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "gssapiServiceName" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "gssapiServiceName" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "gssapiServiceName" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "gssapiServiceName" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "gssapiServiceName" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "password" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "password" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "password" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "password" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "password" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "password" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "replicaSet" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "replicaSet" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "replicaSet" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "replicaSet" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "replicaSet" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "replicaSet" URI option, document given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "username" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "username" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "username" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "username" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "username" URI option, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected string for "username" URI option, document given Testing document options: OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected array or object for "authMechanismProperties" URI option, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected array or object for "authMechanismProperties" URI option, double given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected array or object for "authMechanismProperties" URI option, 32-bit integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected array or object for "authMechanismProperties" URI option, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected array or object for "authMechanismProperties" URI option, ObjectId given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected array or object for "authMechanismProperties" URI option, array given ===DONE=== mongodb-1.3.4/tests/manager/manager-debug-001.phpt0000664000175000017500000000126413210321137021445 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Writing debug log files --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- %A[%s] PHONGO: DEBUG > Connection string: '%s' [%s] PHONGO: DEBUG > Creating Manager, phongo-1.%d.%d%S[%s] - mongoc-1.%s(%s), libbson-1.%s(%s), php-%s %A===DONE===%A mongodb-1.3.4/tests/manager/manager-debug-002.phpt0000664000175000017500000000072213210321137021444 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: mongodb.debug=stderr --SKIPIF-- --INI-- mongodb.debug=stderr --FILE-- ===DONE=== --EXPECTF-- %A[%s] PHONGO: DEBUG > Connection string: '%s' [%s] PHONGO: DEBUG > Creating Manager, phongo-1.%d.%d%S[%s] - mongoc-1.%s(%s), libbson-1.%s(%s), php-%s %A===DONE===%A mongodb-1.3.4/tests/manager/manager-destruct-001.phpt0000664000175000017500000000207513210321137022215 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.3.4/tests/manager/manager-executeBulkWrite-001.phpt0000664000175000017500000000245413210321137023654 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.3.4/tests/manager/manager-executeBulkWrite-002.phpt0000664000175000017500000000313413210321137023651 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.3.4/tests/manager/manager-executeBulkWrite-003.phpt0000664000175000017500000000214613210321137023654 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.3.4/tests/manager/manager-executeBulkWrite-004.phpt0000664000175000017500000000202513210321137023651 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.3.4/tests/manager/manager-executeBulkWrite-005.phpt0000664000175000017500000000163313210321137023656 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.3.4/tests/manager/manager-executeBulkWrite-006.phpt0000664000175000017500000000370613210321137023662 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.3.4/tests/manager/manager-executeBulkWrite-007.phpt0000664000175000017500000000222213210321137023653 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.3.4/tests/manager/manager-executeBulkWrite-008.phpt0000664000175000017500000000300613210321137023655 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.3.4/tests/manager/manager-executeBulkWrite-009.phpt0000664000175000017500000000201613210321137023656 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.3.4/tests/manager/manager-executeBulkWrite-010.phpt0000664000175000017500000000202313210321137023644 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.3.4/tests/manager/manager-executeBulkWrite-011.phpt0000664000175000017500000000421613210321137023653 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 Document failed validation OK: Got MongoDB\Driver\Exception\BulkWriteException 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.3.4/tests/manager/manager-executeBulkWrite_error-001.phpt0000664000175000017500000000276013210321137025065 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: 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.3.4/tests/manager/manager-executeBulkWrite_error-002.phpt0000664000175000017500000000357413210321137025072 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: Multiple write errors: "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.3.4/tests/manager/manager-executeBulkWrite_error-003.phpt0000664000175000017500000000262113210321137025063 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: 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.3.4/tests/manager/manager-executeBulkWrite_error-004.phpt0000664000175000017500000000273113210321137025066 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: 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.3.4/tests/manager/manager-executeBulkWrite_error-006.phpt0000664000175000017500000000225013210321137025064 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: 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.3.4/tests/manager/manager-executeBulkWrite_error-007.phpt0000664000175000017500000000233413210321137025070 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() should not issue warning before exception --SKIPIF-- --FILE-- 1]); echo throws(function() use ($manager) { $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(['x' => 1]); $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 = new MongoDB\Driver\BulkWrite; $bulk->insert(['x' => 1]); $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.3.4/tests/manager/manager-executeBulkWrite_error-008.phpt0000664000175000017500000000112613210321137025067 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() with empty BulkWrite --SKIPIF-- --FILE-- executeBulkWrite(NS, new MongoDB\Driver\BulkWrite); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot do an empty bulk write ===DONE=== mongodb-1.3.4/tests/manager/manager-executeCommand-001.phpt0000664000175000017500000000271113210321137023316 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 (%d) { ["command"]=> object(stdClass)#%d (1) { ["ping"]=> int(1) } } bool(true) object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> NULL ["query"]=> NULL ["command"]=> object(MongoDB\Driver\Command)#%d (%d) { ["command"]=> object(stdClass)#%d (%d) { ["ping"]=> int(1) } } ["readPreference"]=> NULL ["isDead"]=> bool(false) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } Dumping response document: object(stdClass)#%d (%d) { ["ok"]=> float(1) } bool(true) string(%d) "%s" int(%d) ===DONE=== mongodb-1.3.4/tests/manager/manager-executeCommand_error-001.phpt0000664000175000017500000000225313210321137024530 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.3.4/tests/manager/manager-executeQuery-001.phpt0000664000175000017500000000345713210321137023055 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) { ["database"]=> string(6) "phongo" ["collection"]=> string(32) "manager_manager_executeQuery_001" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(3) } ["options"]=> object(stdClass)#%d (%d) { ["projection"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> NULL ["isDead"]=> bool(false) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } bool(true) string(%d) "%s" int(%d) array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } ===DONE=== mongodb-1.3.4/tests/manager/manager-executeQuery-002.phpt0000664000175000017500000000345213210321137023051 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) { ["database"]=> string(6) "phongo" ["collection"]=> string(32) "manager_manager_executeQuery_002" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(3) } ["options"]=> object(stdClass)#%d (%d) { ["projection"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> NULL ["isDead"]=> bool(false) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } bool(true) string(%d) "%s" int(%d) array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } ===DONE=== mongodb-1.3.4/tests/manager/manager-executeQuery-005.phpt0000664000175000017500000000331613210321137023053 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.3.4/tests/manager/manager-executeQuery_error-001.phpt0000664000175000017500000000217013210321137024255 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.3.4/tests/manager/manager-getreadconcern-001.phpt0000664000175000017500000000305313210321137023340 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) { } 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.3.4/tests/manager/manager-getreadpreference-001.phpt0000664000175000017500000000442513210321137024033 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"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(2) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" ["use"]=> string(7) "reports" } [1]=> object(stdClass)#%d (%d) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(2) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" ["use"]=> string(7) "reports" } [1]=> object(stdClass)#%d (%d) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(1) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ca" } } } ===DONE=== mongodb-1.3.4/tests/manager/manager-getservers-001.phpt0000664000175000017500000000214513210321137022547 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.3.4/tests/manager/manager-getservers-002.phpt0000664000175000017500000000261713210321137022554 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.3.4/tests/manager/manager-getwriteconcern-001.phpt0000664000175000017500000000412513210321137023560 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) { } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["j"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["j"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["j"]=> bool(false) } object(MongoDB\Driver\WriteConcern)#%d (%d) { } object(MongoDB\Driver\WriteConcern)#%d (%d) { } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(12) "customTagSet" ["wtimeout"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/manager/manager-invalidnamespace.phpt0000664000175000017500000000161113210321137023360 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.3.4/tests/manager/manager-selectserver-001.phpt0000664000175000017500000000404513210321137023065 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.3.4/tests/manager/manager-selectserver_error-001.phpt0000664000175000017500000000222113210321137024270 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.3.4/tests/manager/manager-set-uri-options-001.phpt0000664000175000017500000000237713210321137023446 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.3.4/tests/manager/manager-set-uri-options-002.phpt0000664000175000017500000000245213210321137023441 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.3.4/tests/manager/manager-var-dump-001.phpt0000664000175000017500000000314413210321137022111 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(0) { } } 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(%d) { ["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) %a } ["round_trip_time"]=> int(%d) } } } ===DONE=== mongodb-1.3.4/tests/manager/manager-wakeup.phpt0000664000175000017500000000110513210321137021347 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.3.4/tests/manager/manager_error-001.phpt0000664000175000017500000000041213210321137021564 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyManager may not inherit from final class (MongoDB\Driver\Manager) in %s on line %d mongodb-1.3.4/tests/query/bug0430-001.phpt0000664000175000017500000000072113210321137017563 0ustar jmikolajmikola--TEST-- PHPC-430: Query constructor arguments are modified --SKIPIF-- --FILE-- ['x' => 1]]; $query = new MongoDB\Driver\Query($filter, $options); var_dump($filter); var_dump($options); ?> ===DONE=== --EXPECT-- array(0) { } array(1) { ["sort"]=> array(1) { ["x"]=> int(1) } } ===DONE=== mongodb-1.3.4/tests/query/bug0430-002.phpt0000664000175000017500000000112113210321137017557 0ustar jmikolajmikola--TEST-- PHPC-430: Query constructor arguments are modified --SKIPIF-- --FILE-- ['x' => 1]]; $optionsCopy = $options; $optionsCopy['cursorFlags'] = 0; $query = new MongoDB\Driver\Query([], $options); var_dump($options); var_dump($optionsCopy); ?> ===DONE=== --EXPECT-- array(1) { ["sort"]=> array(1) { ["x"]=> int(1) } } array(2) { ["sort"]=> array(1) { ["x"]=> int(1) } ["cursorFlags"]=> int(0) } ===DONE=== mongodb-1.3.4/tests/query/bug0430-003.phpt0000664000175000017500000000101113210321137017556 0ustar jmikolajmikola--TEST-- PHPC-430: Query constructor arguments are modified --SKIPIF-- --FILE-- []]; $query = buildQuery($filter, $options); var_dump($options); ?> ===DONE=== --EXPECT-- array(1) { ["sort"]=> array(0) { } } ===DONE=== mongodb-1.3.4/tests/query/bug0705-001.phpt0000664000175000017500000000266513210321137017601 0ustar jmikolajmikola--TEST-- PHPC-705: Do not unnecessarily wrap filters in $query (profiled query) --SKIPIF-- --FILE-- 2]); $cursor = $manager->executeCommand(DATABASE_NAME, $command); $result = current($cursor->toArray()); printf("Set profile level to 2 successfully: %s\n", (empty($result->ok) ? 'no' : 'yes')); $manager->executeQuery(NS, new MongoDB\Driver\Query(["x" => 1])); $query = new MongoDB\Driver\Query( [ 'op' => 'query', 'ns' => NS, ], [ 'sort' => ['ts' => -1], 'limit' => 1, ] ); $cursor = $manager->executeQuery(DATABASE_NAME . '.system.profile', $query); $profileEntry = current($cursor->toArray()); var_dump($profileEntry->query); $command = new MongoDB\Driver\Command(array('profile' => 0)); $cursor = $manager->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) { ["x"]=> int(1) } Set profile level to 0 successfully: yes ===DONE=== mongodb-1.3.4/tests/query/bug0705-002.phpt0000664000175000017500000000111513210321137017567 0ustar jmikolajmikola--TEST-- PHPC-705: Do not unnecessarily wrap filters in $query (currentOp query) --SKIPIF-- --FILE-- executeQuery('admin.$cmd.sys.inprog', new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- array(1) { [0]=> object(stdClass)#%d (%d) { ["inprog"]=> array(0) { } } } ===DONE=== mongodb-1.3.4/tests/query/query-ctor-001.phpt0000664000175000017500000000330713210321137020614 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction 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(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($document)); 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.3.4/tests/query/query-ctor-002.phpt0000664000175000017500000000601713210321137020616 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction with options --FILE-- 1], [ 'allowPartialResults' => false, 'awaitData' => false, 'batchSize' => 10, 'collation' => ['locale' => 'en_US'], 'comment' => 'foo', 'exhaust' => false, 'limit' => 20, 'max' => ['y' => 100], 'maxScan' => 50, 'maxTimeMS' => 1000, 'min' => ['y' => 1], 'noCursorTimeout' => false, 'oplogReplay' => false, 'projection' => ['x' => 1, 'y' => 1], 'returnKey' => false, 'showRecordId' => false, 'singleBatch' => false, 'skip' => 5, 'sort' => ['y' => -1], 'snapshot' => false, 'tailable' => false, ] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], ['hint' => 'y_1'] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], ['hint' => ['y' => 1]] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], ['readConcern' => new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL)] )); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["allowPartialResults"]=> bool(false) ["awaitData"]=> bool(false) ["batchSize"]=> int(10) ["collation"]=> object(stdClass)#%d (%d) { ["locale"]=> string(5) "en_US" } ["comment"]=> string(3) "foo" ["exhaust"]=> bool(false) ["max"]=> object(stdClass)#%d (%d) { ["y"]=> int(100) } ["maxScan"]=> int(50) ["maxTimeMS"]=> int(1000) ["min"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } ["noCursorTimeout"]=> bool(false) ["oplogReplay"]=> bool(false) ["projection"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) ["y"]=> int(1) } ["returnKey"]=> bool(false) ["showRecordId"]=> bool(false) ["skip"]=> int(5) ["sort"]=> object(stdClass)#%d (%d) { ["y"]=> int(-1) } ["snapshot"]=> bool(false) ["tailable"]=> bool(false) ["limit"]=> int(20) ["singleBatch"]=> bool(false) } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["hint"]=> string(3) "y_1" } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["hint"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> array(1) { ["level"]=> string(5) "local" } } ===DONE=== mongodb-1.3.4/tests/query/query-ctor-003.phpt0000664000175000017500000000422413210321137020615 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction with modifier options --FILE-- 1], [ 'modifiers' => [ '$comment' => 'foo', '$max' => ['y' => 100], '$maxScan' => 50, '$maxTimeMS' => 1000, '$min' => ['y' => 1], '$orderby' => ['y' => -1], '$returnKey' => false, '$showDiskLoc' => false, '$snapshot' => false, ], ] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], ['modifiers' => ['$explain' => true]] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], ['modifiers' => ['$hint' => 'y_1']] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], ['modifiers' => ['$hint' => ['y' => 1]]] )); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["comment"]=> string(3) "foo" ["max"]=> object(stdClass)#%d (%d) { ["y"]=> int(100) } ["maxScan"]=> int(50) ["maxTimeMS"]=> int(1000) ["min"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } ["returnKey"]=> bool(false) ["showRecordId"]=> bool(false) ["sort"]=> object(stdClass)#%d (%d) { ["y"]=> int(-1) } ["snapshot"]=> bool(false) } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["explain"]=> bool(true) } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["hint"]=> string(3) "y_1" } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["hint"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } } ["readConcern"]=> NULL } ===DONE=== mongodb-1.3.4/tests/query/query-ctor-004.phpt0000664000175000017500000000427513210321137020624 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction with options overriding modifiers --FILE-- 1], [ 'comment' => 'foo', 'max' => ['y' => 100], 'maxScan' => 50, 'maxTimeMS' => 1000, 'min' => ['y' => 1], 'returnKey' => false, 'showRecordId' => false, 'sort' => ['y' => -1], 'snapshot' => false, 'modifiers' => [ '$comment' => 'bar', '$max' => ['y' => 200], '$maxScan' => 60, '$maxTimeMS' => 2000, '$min' => ['y' => 101], '$orderby' => ['y' => 1], '$returnKey' => true, '$showDiskLoc' => true, '$snapshot' => true, ], ] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], [ 'hint' => 'y_1', 'modifiers' => ['$hint' => 'x_1'], ] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], [ 'hint' => ['y' => 1], 'modifiers' => ['$hint' => ['x' => 1]], ] )); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["comment"]=> string(3) "foo" ["max"]=> object(stdClass)#%d (%d) { ["y"]=> int(100) } ["maxScan"]=> int(50) ["maxTimeMS"]=> int(1000) ["min"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } ["returnKey"]=> bool(false) ["showRecordId"]=> bool(false) ["sort"]=> object(stdClass)#%d (%d) { ["y"]=> int(-1) } ["snapshot"]=> bool(false) } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["hint"]=> string(3) "y_1" } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["hint"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } } ["readConcern"]=> NULL } ===DONE=== mongodb-1.3.4/tests/query/query-ctor-005.phpt0000664000175000017500000000150313210321137020614 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction with negative limit --FILE-- 1], ['limit' => -5] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], [ 'limit' => -5, 'singleBatch' => true ] )); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["limit"]=> int(5) ["singleBatch"]=> bool(true) } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["limit"]=> int(5) ["singleBatch"]=> bool(true) } ["readConcern"]=> NULL } ===DONE=== mongodb-1.3.4/tests/query/query-ctor-006.phpt0000664000175000017500000000151513210321137020620 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction "allowPartialResults" overrides "partial" option --FILE-- 1], ['partial' => true] )); var_dump(new MongoDB\Driver\Query( ['x' => 1], [ 'allowPartialResults' => false, 'partial' => true, ] )); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["allowPartialResults"]=> bool(true) } ["readConcern"]=> NULL } object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } ["options"]=> object(stdClass)#%d (%d) { ["allowPartialResults"]=> bool(false) } ["readConcern"]=> NULL } ===DONE=== mongodb-1.3.4/tests/query/query-ctor_error-001.phpt0000664000175000017500000000275413210321137022032 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction (invalid readConcern type) --SKIPIF-- --FILE-- $test]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; } ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "readConcern" option to be MongoDB\Driver\ReadConcern, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "readConcern" option to be MongoDB\Driver\ReadConcern, %r(double|float)%r given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "readConcern" option to be MongoDB\Driver\ReadConcern, string given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "readConcern" option to be MongoDB\Driver\ReadConcern, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "readConcern" option to be MongoDB\Driver\ReadConcern, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "readConcern" option to be MongoDB\Driver\ReadConcern, object given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "readConcern" option to be MongoDB\Driver\ReadConcern, %r(null|NULL)%r given ===DONE=== mongodb-1.3.4/tests/query/query-ctor_error-002.phpt0000664000175000017500000000442413210321137022027 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction (invalid option types) --FILE-- 0], ['collation' => 0], ['comment' => 0], ['hint' => 0], ['max' => 0], ['min' => 0], ['projection' => 0], ['sort' => 0], ['modifiers' => ['$comment' => 0]], ['modifiers' => ['$hint' => 0]], ['modifiers' => ['$max' => 0]], ['modifiers' => ['$min' => 0]], ['modifiers' => ['$orderby' => 0]], ]; foreach ($tests as $options) { echo throws(function() use ($options) { new MongoDB\Driver\Query([], $options); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n\n"; } ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "modifiers" option to be array, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "collation" option to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "comment" option to be string, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "hint" option to be string, array, or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "max" option to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "min" option to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "projection" option to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "sort" option to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "$comment" modifier to be string, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "$hint" modifier to be string, array, or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "$max" modifier to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "$min" modifier to be array or object, integer given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "$orderby" modifier to be array or object, integer given ===DONE=== mongodb-1.3.4/tests/query/query-ctor_error-003.phpt0000664000175000017500000000076213210321137022031 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction (negative limit conflicts with false singleBatch) --FILE-- -1, 'singleBatch' => false]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Negative "limit" option conflicts with false "singleBatch" option ===DONE=== mongodb-1.3.4/tests/query/query-ctor_error-004.phpt0000664000175000017500000000407713210321137022035 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction (cannot use empty keys in documents) --FILE-- '1'], []], [['x' => ['' => '1']], []], [[], ['collation' => ['' => 1]]], [[], ['hint' => ['' => 1]]], [[], ['max' => ['' => 1]]], [[], ['min' => ['' => 1]]], [[], ['projection' => ['' => 1]]], [[], ['sort' => ['' => 1]]], [[], ['modifiers' => ['$hint' => ['' => 1]]]], [[], ['modifiers' => ['$max' => ['' => 1]]]], [[], ['modifiers' => ['$min' => ['' => 1]]]], [[], ['modifiers' => ['$orderby' => ['' => 1]]]], ]; foreach ($tests as $test) { list($filter, $options) = $test; echo throws(function() use ($filter, $options) { new MongoDB\Driver\Query($filter, $options); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; } ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in filter document OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in filter document OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "collation" option OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "hint" option OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "max" option OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "min" option OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "projection" option OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "sort" option OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "$hint" modifier OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "$max" modifier OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "$min" modifier OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot use empty keys in "$orderby" modifier ===DONE=== mongodb-1.3.4/tests/query/query-ctor_error-005.phpt0000664000175000017500000000070413210321137022027 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction (invalid maxAwaitTimeMS range) --FILE-- -1]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "maxAwaitTimeMS" option to be >= 0, -1 given ===DONE=== mongodb-1.3.4/tests/query/query-ctor_error-006.phpt0000664000175000017500000000106313210321137022027 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query construction (invalid maxAwaitTimeMS range) --SKIPIF-- --FILE-- 4294967296]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected "maxAwaitTimeMS" option to be <= 4294967295, 4294967296 given ===DONE=== mongodb-1.3.4/tests/query/query-debug-001.phpt0000664000175000017500000000215113210321137020727 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query debug output --SKIPIF-- --FILE-- 123], [ 'limit' => 5, 'modifiers' => [ '$comment' => 'foo', '$maxTimeMS' => 500, ], 'projection' => ['c' => 1], 'readConcern' => new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL), 'skip' => 10, 'sort' => ['b' => -1], ] )); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["a"]=> int(123) } ["options"]=> object(stdClass)#%d (%d) { ["comment"]=> string(3) "foo" ["maxTimeMS"]=> int(500) ["projection"]=> object(stdClass)#%d (%d) { ["c"]=> int(1) } ["skip"]=> int(10) ["sort"]=> object(stdClass)#%d (%d) { ["b"]=> int(-1) } ["limit"]=> int(5) } ["readConcern"]=> array(1) { ["level"]=> string(5) "local" } } ===DONE=== mongodb-1.3.4/tests/query/query_error-001.phpt0000664000175000017500000000040013210321137021047 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyQuery may not inherit from final class (MongoDB\Driver\Query) in %s on line %d mongodb-1.3.4/tests/readConcern/readconcern-bsonserialize-001.phpt0000664000175000017500000000112413210321137024705 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern::bsonSerialize() --FILE-- ===DONE=== --EXPECT-- { } { "level" : "linearizable" } { "level" : "local" } { "level" : "majority" } ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-bsonserialize-002.phpt0000664000175000017500000000137313210321137024714 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern::bsonSerialize() returns an object --FILE-- bsonSerialize()); } ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { } object(stdClass)#%d (%d) { ["level"]=> string(12) "linearizable" } object(stdClass)#%d (%d) { ["level"]=> string(5) "local" } object(stdClass)#%d (%d) { ["level"]=> string(8) "majority" } ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-constants.phpt0000664000175000017500000000067013210321137023557 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern constants --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- string(12) "linearizable" string(5) "local" string(8) "majority" ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-ctor-001.phpt0000664000175000017500000000160213210321137023004 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern construction --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadConcern)#%d (%d) { } object(MongoDB\Driver\ReadConcern)#%d (%d) { } 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" } ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-ctor_error-001.phpt0000664000175000017500000000120113210321137024210 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern construction (invalid arguments) --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\Driver\ReadConcern::__construct() expects at most 1 parameter, 2 given ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-ctor_error-002.phpt0000664000175000017500000000157013210321137024222 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern construction (invalid level type) --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\Driver\ReadConcern::__construct() expects parameter 1 to be string, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\Driver\ReadConcern::__construct() expects parameter 1 to be string, object given ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-debug-001.phpt0000664000175000017500000000143413210321137023126 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern debug output --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadConcern)#%d (%d) { } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(12) "linearizable" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(5) "local" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(8) "majority" } ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-getlevel-001.phpt0000664000175000017500000000104313210321137023643 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern::getLevel() --SKIPIF-- --FILE-- getLevel()); } ?> ===DONE=== --EXPECT-- NULL string(5) "local" string(8) "majority" string(17) "not-yet-supported" ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern-isdefault-001.phpt0000664000175000017500000000212313210321137024014 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern::isDefault() --FILE-- getReadConcern(), (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?readconcernlevel='))->getReadConcern(), (new MongoDB\Driver\Manager(null, ['readconcernlevel' => 'local']))->getReadConcern(), (new MongoDB\Driver\Manager(null, ['readconcernlevel' => '']))->getReadConcern(), // Cannot test ['readconcernlevel' => null] since a string type is expected (PHPC-887) (new MongoDB\Driver\Manager)->getReadConcern(), ]; foreach ($tests as $rc) { var_dump($rc->isDefault()); } ?> ===DONE=== --EXPECT-- bool(true) bool(true) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(true) ===DONE=== mongodb-1.3.4/tests/readConcern/readconcern_error-001.phpt0000664000175000017500000000043613210321137023254 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadConcern cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyReadConcern may not inherit from final class (MongoDB\Driver\ReadConcern) in %s on line %d mongodb-1.3.4/tests/readPreference/bug0146-001.phpt0000664000175000017500000001037513210321137021342 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) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_001" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_001" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_001" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_001" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_001" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } ===DONE=== mongodb-1.3.4/tests/readPreference/bug0146-002.phpt0000664000175000017500000001042013210321137021332 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) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_002" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_002" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_002" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_002" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } object(MongoDB\Driver\Cursor)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(26) "readPreference_bug0146_002" ["query"]=> object(MongoDB\Driver\Query)#%d (%d) { ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } ["options"]=> object(stdClass)#%d (%d) { } ["readConcern"]=> NULL } ["command"]=> NULL ["readPreference"]=> object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } ["isDead"]=> bool(true) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } ===DONE=== mongodb-1.3.4/tests/readPreference/bug0851-001.phpt0000664000175000017500000000146013210321137021340 0ustar jmikolajmikola--TEST-- PHPC-851: ReadPreference constructor should not modify tagSets argument --FILE-- 'ny'], [], ]; $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED, $tagSets); var_dump($tagSets); /* Dump the Manager's ReadPreference to ensure that each element in the $tagSets * argument was converted to an object. */ var_dump($rp); ?> ===DONE=== --EXPECTF-- array(2) { [0]=> array(1) { ["dc"]=> string(2) "ny" } [1]=> array(0) { } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" ["tags"]=> array(2) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" } [1]=> object(stdClass)#%d (%d) { } } } ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-bsonserialize-001.phpt0000664000175000017500000000275413210321137026075 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::bsonSerialize() --FILE-- 'ny']]), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []]), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000]), ]; foreach ($tests as $test) { echo toJSON(fromPHP($test)), "\n"; } ?> ===DONE=== --EXPECT-- { "mode" : "primary" } { "mode" : "primaryPreferred" } { "mode" : "secondary" } { "mode" : "secondaryPreferred" } { "mode" : "nearest" } { "mode" : "primary" } { "mode" : "secondary", "tags" : [ { "dc" : "ny" } ] } { "mode" : "secondary", "tags" : [ { "dc" : "ny" }, { "dc" : "sf", "use" : "reporting" }, { } ] } { "mode" : "secondary", "maxStalenessSeconds" : 1000 } ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-bsonserialize-002.phpt0000664000175000017500000000424313210321137026071 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::bsonSerialize() returns an object --FILE-- 'ny']]), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []]), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000]), ]; foreach ($tests as $test) { var_dump($test->bsonSerialize()); } ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["mode"]=> string(7) "primary" } object(stdClass)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } object(stdClass)#%d (%d) { ["mode"]=> string(9) "secondary" } object(stdClass)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(stdClass)#%d (%d) { ["mode"]=> string(7) "nearest" } object(stdClass)#%d (%d) { ["mode"]=> string(7) "primary" } object(stdClass)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(1) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" } } } object(stdClass)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(3) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" } [1]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "sf" ["use"]=> string(9) "reporting" } [2]=> object(stdClass)#%d (%d) { } } } object(stdClass)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-ctor-001.phpt0000664000175000017500000000202213210321137024157 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction --FILE-- 'one']])); var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, [])); var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000])); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(1) { [0]=> object(stdClass)#%d (%d) { ["tag"]=> string(3) "one" } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-ctor-002.phpt0000664000175000017500000000400013210321137024156 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction with strings --FILE-- getMessage(), "\n"; } var_dump( $rp ); } ?> --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } mongodb-1.3.4/tests/readPreference/readpreference-ctor_error-001.phpt0000664000175000017500000000060713210321137025377 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction (invalid mode) --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid mode: 42 ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-ctor_error-002.phpt0000664000175000017500000000327113210321137025400 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction (invalid tagSets) --FILE-- 'one']]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference("primary", [['tag' => 'one']]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, ['invalid']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, ['invalid']); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; // Ensure that tagSets is validated before maxStalenessSeconds option echo throws(function() { new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, ['invalid'], ['maxStalenessSeconds' => -2]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException tagSets may not be used with primary mode OK: Got MongoDB\Driver\Exception\InvalidArgumentException tagSets may not be used with primary mode OK: Got MongoDB\Driver\Exception\InvalidArgumentException tagSets must be an array of zero or more documents OK: Got MongoDB\Driver\Exception\InvalidArgumentException tagSets must be an array of zero or more documents OK: Got MongoDB\Driver\Exception\InvalidArgumentException tagSets must be an array of zero or more documents ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-ctor_error-003.phpt0000664000175000017500000000334613210321137025404 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction (invalid maxStalenessSeconds) --FILE-- 1000]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference("primary", null, ['maxStalenessSeconds' => 1000]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => -2]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 0]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 42]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException maxStalenessSeconds may not be used with primary mode OK: Got MongoDB\Driver\Exception\InvalidArgumentException maxStalenessSeconds may not be used with primary mode OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be >= 90, -2 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be >= 90, 0 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be >= 90, 42 given ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-ctor_error-004.phpt0000664000175000017500000000117213210321137025400 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction (invalid maxStalenessSeconds range) --SKIPIF-- --FILE-- 2147483648]); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected maxStalenessSeconds to be <= 2147483647, 2147483648 given ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-ctor_error-005.phpt0000664000175000017500000000064213210321137025402 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction (invalid string mode) --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid mode: 'hocuspocus' ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-ctor_error-006.phpt0000664000175000017500000000070213210321137025400 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction (invalid type for mode) --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected mode to be integer or string, %r(double|float)%r given ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-debug-001.phpt0000664000175000017500000000447113210321137024310 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference debug output --FILE-- 'ny']]), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []]), new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, null, ['maxStalenessSeconds' => 1000]), ]; foreach ($tests as $test) { var_dump($test); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(16) "primaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(18) "secondaryPreferred" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "nearest" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(7) "primary" } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(1) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["tags"]=> array(3) { [0]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "ny" } [1]=> object(stdClass)#%d (%d) { ["dc"]=> string(2) "sf" ["use"]=> string(9) "reporting" } [2]=> object(stdClass)#%d (%d) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> string(9) "secondary" ["maxStalenessSeconds"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-getMaxStalenessMS-001.phpt0000664000175000017500000000113713210321137026565 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::getMaxStalenessSeconds() --FILE-- $test]); var_dump($rp->getMaxStalenessSeconds()); } ?> ===DONE=== --EXPECT-- int(-1) int(90) int(90) int(1000) int(2147483647) ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-getMaxStalenessMS-002.phpt0000664000175000017500000000112013210321137026556 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::getMaxStalenessSeconds() with string mode --FILE-- $test]); var_dump($rp->getMaxStalenessSeconds()); } ?> ===DONE=== --EXPECT-- int(-1) int(90) int(90) int(1000) int(2147483647) ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-getMode-001.phpt0000664000175000017500000000103713210321137024601 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::getMode() --FILE-- getMode()); } ?> ===DONE=== --EXPECT-- int(1) int(5) int(2) int(6) int(10) ===DONE=== mongodb-1.3.4/tests/readPreference/readpreference-getTagSets-001.phpt0000664000175000017500000000133213210321137025265 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::getTagSets() --FILE-- 'ny'], []], [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []], ]; 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.3.4/tests/readPreference/readpreference-getTagSets-002.phpt0000664000175000017500000000131213210321137025264 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::getTagSets() with string mode --FILE-- 'ny'], []], [['dc' => 'ny'], ['dc' => 'sf', 'use' => 'reporting'], []], ]; foreach ($tests as $test) { $rp = new MongoDB\Driver\ReadPreference("secondaryPreferred", $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.3.4/tests/readPreference/readpreference_error-001.phpt0000664000175000017500000000045513210321137024433 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyReadPreference may not inherit from final class (MongoDB\Driver\ReadPreference) in %s on line %d mongodb-1.3.4/tests/replicaset/bug0155.phpt0000664000175000017500000000141513210321137020260 0ustar jmikolajmikola--TEST-- PHPC-155: WriteConcernError->getInfo() can be scalar --SKIPIF-- --FILE-- insert(array('example' => 'document')); try { $manager->executeBulkWrite(NS, $bulk, $wc); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcernError)#%d (%d) { ["message"]=> string(%d) "%s" ["code"]=> int(79) ["info"]=> NULL } ===DONE=== mongodb-1.3.4/tests/replicaset/bug0898-001.phpt0000664000175000017500000000174413210321137020601 0ustar jmikolajmikola--TEST-- PHPC-898: readConcern option should not be included in getMore commands (URI option) --SKIPIF-- --FILE-- 'local']); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $result = $manager->executeBulkWrite(NS, $bulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); $query = new MongoDB\Driver\Query([], ['batchSize' => 2]); $cursor = $manager->executeQuery(NS, $query); foreach ($cursor as $document) { var_dump($document); } ?> ===DONE=== --EXPECTF-- Inserted 3 document(s) object(stdClass)#%d (1) { ["_id"]=> int(1) } object(stdClass)#%d (1) { ["_id"]=> int(2) } object(stdClass)#%d (1) { ["_id"]=> int(3) } ===DONE=== mongodb-1.3.4/tests/replicaset/bug0898-002.phpt0000664000175000017500000000204413210321137020574 0ustar jmikolajmikola--TEST-- PHPC-898: readConcern option should not be included in getMore commands (query option) --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $result = $manager->executeBulkWrite(NS, $bulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); $rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL); $query = new MongoDB\Driver\Query([], ['batchSize' => 2, 'readConcern' => $rc]); $cursor = $manager->executeQuery(NS, $query); foreach ($cursor as $document) { var_dump($document); } ?> ===DONE=== --EXPECTF-- Inserted 3 document(s) object(stdClass)#%d (1) { ["_id"]=> int(1) } object(stdClass)#%d (1) { ["_id"]=> int(2) } object(stdClass)#%d (1) { ["_id"]=> int(3) } ===DONE=== mongodb-1.3.4/tests/replicaset/manager-getservers-001.phpt0000664000175000017500000000464413210321137023276 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::getServers() --SKIPIF-- --FILE-- "document"); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); $wresult = $manager->executeBulkWrite(NS, $bulk); var_dump($manager->getServers()); $servers = $manager->getServers(); foreach($servers as $server) { printf("%s:%d - primary: %d, secondary: %d, arbiter: %d\n", $server->getHost(), $server->getPort(), $server->isPrimary(), $server->isSecondary(), $server->isArbiter()); } ?> ===DONE=== --EXPECTF-- array(3) { [0]=> object(MongoDB\Driver\Server)#%d (%d) { ["host"]=> string(14) "192.168.112.10" ["port"]=> int(3000) ["type"]=> int(4) ["is_primary"]=> bool(true) ["is_secondary"]=> bool(false) ["is_arbiter"]=> bool(false) ["is_hidden"]=> bool(false) ["is_passive"]=> bool(false) ["tags"]=> array(%d) { ["dc"]=> string(2) "pa" ["ordinal"]=> string(3) "one" } ["last_is_master"]=> array(%d) { %a } ["round_trip_time"]=> int(%d) } [1]=> object(MongoDB\Driver\Server)#%d (%d) { ["host"]=> string(14) "192.168.112.10" ["port"]=> int(3001) ["type"]=> int(5) ["is_primary"]=> bool(false) ["is_secondary"]=> bool(true) ["is_arbiter"]=> bool(false) ["is_hidden"]=> bool(false) ["is_passive"]=> bool(false) ["tags"]=> array(%d) { ["dc"]=> string(3) "nyc" ["ordinal"]=> string(3) "two" } ["last_is_master"]=> array(%d) { %a } ["round_trip_time"]=> int(%d) } [2]=> object(MongoDB\Driver\Server)#%d (%d) { ["host"]=> string(14) "192.168.112.10" ["port"]=> int(3002) ["type"]=> int(6) ["is_primary"]=> bool(false) ["is_secondary"]=> bool(false) ["is_arbiter"]=> bool(true) ["is_hidden"]=> bool(false) ["is_passive"]=> bool(false) ["last_is_master"]=> array(%d) { %a } ["round_trip_time"]=> int(%d) } } 192.168.112.10:3000 - primary: 1, secondary: 0, arbiter: 0 192.168.112.10:3001 - primary: 0, secondary: 1, arbiter: 0 192.168.112.10:3002 - primary: 0, secondary: 0, arbiter: 1 ===DONE=== mongodb-1.3.4/tests/replicaset/manager-selectserver-001.phpt0000664000175000017500000000460613210321137023611 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"); $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)); $result = $server2->executeBulkWrite("local.example", $bulk); var_dump($result->getInsertedCount()); ?> ===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 int(3) ===DONE=== mongodb-1.3.4/tests/replicaset/readconcern-001.phpt0000664000175000017500000000242113210321137021747 0ustar jmikolajmikola--TEST-- ReadConcern: MongoDB\Driver\Manager::executeQuery() with readConcern option (find command) --SKIPIF-- --FILE-- insert(['_id' => 1, 'x' => 1]); $bulk->insert(['_id' => 2, 'x' => 2]); $manager->executeBulkWrite(NS, $bulk, $wc); $rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL); $query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]); $cursor = $manager->executeQuery(NS, $query); var_dump(iterator_to_array($cursor)); $rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::MAJORITY); $query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]); $cursor = $manager->executeQuery(NS, $query); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- array(1) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> int(2) ["x"]=> int(2) } } array(1) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> int(2) ["x"]=> int(2) } } ===DONE=== mongodb-1.3.4/tests/replicaset/readconcern-002.phpt0000664000175000017500000000246213210321137021755 0ustar jmikolajmikola--TEST-- ReadConcern: MongoDB\Driver\Manager::executeQuery() with readConcern option (OP_QUERY) --SKIPIF-- --FILE-- insert(['_id' => 1, 'x' => 1]); $bulk->insert(['_id' => 2, 'x' => 2]); $manager->executeBulkWrite(NS, $bulk); $rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::LOCAL); $query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]); echo throws(function() use ($manager, $query) { $manager->executeQuery(NS, $query); }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; $rc = new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::MAJORITY); $query = new MongoDB\Driver\Query(['x' => 2], ['readConcern' => $rc]); echo throws(function() use ($manager, $query) { $manager->executeQuery(NS, $query); }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\RuntimeException The selected server does not support readConcern OK: Got MongoDB\Driver\Exception\RuntimeException The selected server does not support readConcern ===DONE=== mongodb-1.3.4/tests/replicaset/server-001.phpt0000664000175000017500000000265613210321137021004 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server: Manager->getServer() returning correct server --SKIPIF-- --FILE-- "document"); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); $wresult = $manager->executeBulkWrite(NS, $bulk); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); /* writes go to the primary */ $server = $wresult->getServer(); var_dump( $server->getHost(), $server->getTags(), $server->getLatency(), $server->getPort(), $server->getType() == MongoDB\Driver\Server::TYPE_RS_PRIMARY, $server->isPrimary(), $server->isSecondary(), $server->isArbiter(), $server->isHidden(), $server->isPassive() ); $info = $server->getInfo(); // isMaster output changes between mongod versions var_dump($info["setName"], $info["hosts"]); var_dump($info["me"] == $server->getHost() . ":" . $server->getPort()); ?> ===DONE=== --EXPECTF-- string(14) "192.168.112.10" array(2) { ["dc"]=> string(2) "pa" ["ordinal"]=> string(3) "one" } int(%d) int(3000) bool(true) bool(true) bool(false) bool(false) bool(false) bool(false) string(10) "REPLICASET" array(2) { [0]=> string(19) "192.168.112.10:3000" [1]=> string(19) "192.168.112.10:3001" } bool(true) ===DONE=== mongodb-1.3.4/tests/replicaset/server-002.phpt0000664000175000017500000000257613210321137021006 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server: Manager->getServer() returning correct server --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()), $rp); /* writes go to the primary */ $server = $result->getServer(); var_dump( $server->getHost(), $server->getTags(), $server->getLatency(), $server->getPort(), $server->getType() == MongoDB\Driver\Server::TYPE_RS_SECONDARY, $server->isPrimary(), $server->isSecondary(), $server->isArbiter(), $server->isHidden(), $server->isPassive() ); $info = $server->getInfo(); // isMaster output changes between mongod versions var_dump($info["setName"], $info["hosts"]); var_dump($info["me"] == $server->getHost() . ":" . $server->getPort()); ?> ===DONE=== --EXPECTF-- string(14) "192.168.112.10" array(2) { ["dc"]=> string(3) "nyc" ["ordinal"]=> string(3) "two" } int(%d) int(3001) bool(true) bool(false) bool(true) bool(false) bool(false) bool(false) string(10) "REPLICASET" array(2) { [0]=> string(19) "192.168.112.10:3000" [1]=> string(19) "192.168.112.10:3001" } bool(true) ===DONE=== mongodb-1.3.4/tests/replicaset/writeconcernerror-001.phpt0000664000175000017500000000151213210321137023240 0ustar jmikolajmikola--TEST-- WriteConcernError: Populate WriteConcernError on WriteConcern errors --SKIPIF-- --FILE-- insert(array("my" => "value")); $w = new MongoDB\Driver\WriteConcern(30, 100); try { $retval = $manager->executeBulkWrite(NS, $bulk, $w); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { $server = $e->getWriteResult()->getServer(); $server->getPort(); printWriteResult($e->getWriteResult(), false); } ?> ===DONE=== --EXPECTF-- server: %s:%d insertedCount: 1 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 writeConcernError: %s (%d) ===DONE=== mongodb-1.3.4/tests/replicaset/writeconcernerror-002.phpt0000664000175000017500000000204413210321137023242 0ustar jmikolajmikola--TEST-- WriteConcernError: Access write counts and WriteConcern reason --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)); $w = new MongoDB\Driver\WriteConcern(30); try { $retval = $manager->executeBulkWrite(NS, $bulk, $w); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { printWriteResult($e->getWriteResult(), false); } ?> ===DONE=== --EXPECTF-- server: %s:%d insertedCount: 3 matchedCount: 1 modifiedCount: 1 upsertedCount: 0 deletedCount: 1 writeConcernError: %s (%d) ===DONE=== mongodb-1.3.4/tests/replicaset/writeresult-getserver-001.phpt0000664000175000017500000000215013210321137024060 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server: Manager->getServer() returning correct server --SKIPIF-- --FILE-- "document"); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); $wresult = $manager->executeBulkWrite(NS, $bulk); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); /* writes go to the primary */ $server = $wresult->getServer(); /* This is the same server */ $server2 = $server->executeBulkWrite(NS, $bulk)->getServer(); /* Both are the primary, e.g. the same server */ var_dump($server == $server2); $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY); /* Fetch a secondary */ $server3 = $manager->executeQuery(NS, new MongoDB\Driver\Query(array()), $rp)->getServer(); var_dump($server == $server3); var_dump($server->getPort(), $server3->getPort()); ?> ===DONE=== --EXPECTF-- bool(true) bool(false) int(3000) int(3001) ===DONE=== mongodb-1.3.4/tests/replicaset/writeresult-getserver-002.phpt0000664000175000017500000000453713210321137024074 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server: Manager->getServer() returning correct server --SKIPIF-- --FILE-- "document"); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); $wresult = $manager->executeBulkWrite(NS, $bulk); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); /* writes go to the primary */ $server = $wresult->getServer(); /* This is the same server */ $server2 = $server->executeBulkWrite(NS, $bulk)->getServer(); /* Both are the primary, e.g. the same server */ var_dump($server == $server2); $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY); /* Fetch a secondary */ $server3 = $manager->executeQuery(NS, new MongoDB\Driver\Query(array()), $rp)->getServer(); var_dump($server == $server3); var_dump($server->getPort(), $server3->getPort()); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert($doc); $result = $server3->executeBulkWrite("local.examples", $bulk); var_dump($result, $result->getServer()->getHost(), $result->getServer()->getPort()); $result = $server3->executeQuery("local.examples", new MongoDB\Driver\Query(array())); foreach($result as $document) { var_dump($document); } $cmd = new MongoDB\Driver\Command(array("drop" => "examples")); $server3->executeCommand("local", $cmd); throws(function() use ($server3, $bulk) { $result = $server3->executeBulkWrite(NS, $bulk); }, "MongoDB\\Driver\\Exception\\RuntimeException"); ?> ===DONE=== --EXPECTF-- bool(true) bool(false) int(3000) int(3001) 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"]=> object(MongoDB\Driver\WriteConcern)#%d (%d) { } } string(14) "192.168.112.10" int(3001) object(stdClass)#%d (2) { ["_id"]=> object(%s\ObjectId)#%d (1) { ["oid"]=> string(24) "%s" } ["example"]=> string(8) "document" } OK: Got MongoDB\Driver\Exception\RuntimeException ===DONE=== mongodb-1.3.4/tests/server/bug0671-002.phpt0000664000175000017500000000124713210321137017740 0ustar jmikolajmikola--TEST-- PHPC-671: Segfault if Manager is already freed when using selected Server --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY)); unset($manager); $cursor = $server->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/server/server-constants.phpt0000664000175000017500000000133713210321137021666 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.3.4/tests/server/server-construct-001.phpt0000664000175000017500000000116513210321137022173 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.3.4/tests/server/server-debug.phpt0000664000175000017500000000224413210321137020736 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(%d) { ["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) %a float(1) } ["round_trip_time"]=> int(%d) } ===DONE=== mongodb-1.3.4/tests/server/server-errors.phpt0000664000175000017500000000367713210321137021177 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.3.4/tests/server/server-executeBulkWrite-001.phpt0000664000175000017500000000373613210321137023450 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"]=> object(MongoDB\Driver\WriteConcern)#%d (%d) { } } ===> 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.3.4/tests/server/server-executeBulkWrite-002.phpt0000664000175000017500000000155313210321137023444 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) NULL bool(true) int(1) ===DONE=== mongodb-1.3.4/tests/server/server-executeBulkWrite-003.phpt0000664000175000017500000000164213210321137023444 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) NULL bool(true) int(1) bool(true) int(1) bool(true) int(1) ===DONE=== mongodb-1.3.4/tests/server/server-executeBulkWrite-004.phpt0000664000175000017500000000244713210321137023451 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) NULL 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.3.4/tests/server/server-executeBulkWrite-005.phpt0000664000175000017500000000217013210321137023443 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) NULL bool(true) int(1) ===DONE=== mongodb-1.3.4/tests/server/server-executeBulkWrite_error-001.phpt0000664000175000017500000000130313210321137024645 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeBulkWrite() with empty BulkWrite --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY)); echo throws(function() use ($server) { $server->executeBulkWrite(NS, new MongoDB\Driver\BulkWrite); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Cannot do an empty bulk write ===DONE=== mongodb-1.3.4/tests/server/server-executeCommand-001.phpt0000664000175000017500000000242513210321137023110 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) { ["database"]=> string(6) "phongo" ["collection"]=> NULL ["query"]=> NULL ["command"]=> object(MongoDB\Driver\Command)#%d (%d) { ["command"]=> object(stdClass)#%d (%d) { ["ping"]=> int(1) } } ["readPreference"]=> NULL ["isDead"]=> bool(false) ["currentIndex"]=> int(0) ["currentDocument"]=> NULL ["server"]=> object(MongoDB\Driver\Server)#%d (%d) { %a } } Dumping response document: object(stdClass)#%d (1) { ["ok"]=> float(1) } bool(true) ===DONE=== mongodb-1.3.4/tests/server/server-executeCommand-002.phpt0000664000175000017500000000366013210321137023113 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.3.4/tests/server/server-executeCommand-003.phpt0000664000175000017500000000176713210321137023122 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeCommand() with conflicting read preference for secondary --SKIPIF-- --FILE-- selectServer($secondaryRp); /* Note: this is testing that the read preference (even a conflicting one) has * no effect when directly querying a server, since the slaveOk flag is always * set for hinted commands. */ $primaryRp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY); $cursor = $secondary->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(array('ping' => 1)), $primaryRp); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- array(1) { [0]=> object(stdClass)#%d (%d) { ["ok"]=> float(1) } } ===DONE=== mongodb-1.3.4/tests/server/server-executeQuery-001.phpt0000664000175000017500000000212713210321137022636 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.3.4/tests/server/server-executeQuery-002.phpt0000664000175000017500000000250113210321137022633 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.3.4/tests/server/server-executeQuery-003.phpt0000664000175000017500000000252313210321137022640 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.3.4/tests/server/server-executeQuery-004.phpt0000664000175000017500000000135513210321137022643 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.3.4/tests/server/server-executeQuery-005.phpt0000664000175000017500000000321213210321137022636 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) { ["x"]=> int(1) } Set profile level to 0 successfully: yes ===DONE=== mongodb-1.3.4/tests/server/server-executeQuery-006.phpt0000664000175000017500000000332713210321137022646 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.3.4/tests/server/server-executeQuery-007.phpt0000664000175000017500000000227213210321137022645 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.3.4/tests/server/server-executeQuery-008.phpt0000664000175000017500000000236713210321137022653 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with conflicting read preference for secondary --SKIPIF-- --FILE-- selectServer($primaryRp); $bulk = new \MongoDB\Driver\BulkWrite; $bulk->insert(['_id' => 1, 'x' => 1]); $primary->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY)); $secondaryRp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY); $secondary = $manager->selectServer($secondaryRp); /* Note: this is testing that the read preference (even a conflicting one) has * no effect when directly querying a server, since the slaveOk flag is always * set for hinted queries. */ $cursor = $secondary->executeQuery(NS, new MongoDB\Driver\Query(['x' => 1]), $primaryRp); var_dump($cursor->toArray()); ?> ===DONE=== ( --EXPECTF-- array(1) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> int(1) ["x"]=> int(1) } } ===DONE=== mongodb-1.3.4/tests/server/server-getInfo-001.phpt0000664000175000017500000000150113210321137021534 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::getInfo() --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY))->getInfo()); } catch (Exception $e) {} ?> ===DONE=== --EXPECTF-- array(%d) { ["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) %a float(1) } ===DONE=== mongodb-1.3.4/tests/server/server-getTags-001.phpt0000664000175000017500000000071613210321137021546 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::getTags() with standalone --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY))->getTags()); ?> ===DONE=== --EXPECTF-- array(0) { } ===DONE=== mongodb-1.3.4/tests/server/server-getTags-002.phpt0000664000175000017500000000132613210321137021545 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::getTags() with replica set --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY))->getTags()); var_dump($manager->selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY))->getTags()); ?> ===DONE=== --EXPECTF-- array(2) { ["dc"]=> string(2) "pa" ["ordinal"]=> string(3) "one" } array(2) { ["dc"]=> string(3) "nyc" ["ordinal"]=> string(3) "two" } ===DONE=== mongodb-1.3.4/tests/server/server_error-001.phpt0000664000175000017500000000040513210321137021356 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyServer may not inherit from final class (MongoDB\Driver\Server) in %s on line %d mongodb-1.3.4/tests/standalone/bug0166.phpt0000664000175000017500000000146313210321137020262 0ustar jmikolajmikola--TEST-- Disable serialization of objects --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- bool(false) OK: Got Exception ===DONE=== mongodb-1.3.4/tests/standalone/bug0231.phpt0000664000175000017500000000145413210321137020253 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.3.4/tests/standalone/bug0357.phpt0000664000175000017500000000111413210321137020255 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.3.4/tests/standalone/bug0545.phpt0000664000175000017500000000615113210321137020262 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.3.4/tests/standalone/bug0655.phpt0000664000175000017500000000236113210321137020263 0ustar jmikolajmikola--TEST-- PHPC-655: Use case insensitive parsing for Manager connectTimeoutMS array option --SKIPIF-- --FILE-- 1]); // Invalid host cannot be resolved $manager = new MongoDB\Driver\Manager('mongodb://invalid.host:27017', ['connectTimeoutMS' => 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', ['CONNECTTIMEOUTMS' => 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.3.4/tests/standalone/command-aggregate-001.phpt0000664000175000017500000000171113210321137023024 0ustar jmikolajmikola--TEST-- DRIVERS-289: Test iteration on live command cursor with empty first batch --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $manager->executeBulkWrite(NS, $bulk); $command = new MongoDB\Driver\Command([ 'aggregate' => COLLECTION_NAME, 'pipeline' => [ [ '$match' => [ '_id' => [ '$gt' => 1 ]]], ], 'cursor' => ['batchSize' => 0], ]); $cursor = $manager->executeCommand(DATABASE_NAME, $command); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- array(2) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> int(2) } [1]=> object(stdClass)#%d (%d) { ["_id"]=> int(3) } } ===DONE=== mongodb-1.3.4/tests/standalone/connectiontimeoutexception-001.phpt0000664000175000017500000000141413210321137025147 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.3.4/tests/standalone/executiontimeoutexception-001.phpt0000664000175000017500000000154613210321137025021 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.3.4/tests/standalone/executiontimeoutexception-002.phpt0000664000175000017500000000141513210321137025015 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.3.4/tests/standalone/manager-as-singleton.phpt0000664000175000017500000000266513210321137023210 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.3.4/tests/standalone/query-errors.phpt0000664000175000017500000000244113210321137021644 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.3.4/tests/standalone/update-multi-001.phpt0000664000175000017500000001165013210321137022077 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.3.4/tests/standalone/write-error-001.phpt0000664000175000017500000000150213210321137021741 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.3.4/tests/standalone/writeresult-isacknowledged-001.phpt0000664000175000017500000000174613210321137025044 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"]=> object(MongoDB\Driver\WriteConcern)#%d (%d) { } } ===DONE=== mongodb-1.3.4/tests/standalone/writeresult-isacknowledged-002.phpt0000664000175000017500000000213313210321137025034 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"]=> object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } } ===DONE=== mongodb-1.3.4/tests/standalone/writeresult-isacknowledged-003.phpt0000664000175000017500000000202713210321137025037 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"]=> NULL ["nMatched"]=> NULL ["nModified"]=> NULL ["nRemoved"]=> NULL ["nUpserted"]=> NULL ["upsertedIds"]=> array(0) { } ["writeErrors"]=> array(0) { } ["writeConcernError"]=> NULL ["writeConcern"]=> object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } } ===DONE=== mongodb-1.3.4/tests/utils/PHONGO-FIXTURES.json.gz0000664000175000017500000022370113210321137021057 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.3.4/tests/utils/basic-skipif.inc0000664000175000017500000000017413210321137020340 0ustar jmikolajmikola "", "STANDALONE_24" => "", "STANDALONE_26" => "", "STANDALONE_30" => "", "STANDALONE_SSL" => "", "STANDALONE_AUTH" => "", "STANDALONE_X509" => "", "STANDALONE_PLAIN" => "", "REPLICASET" => "", "REPLICASET_30" => "", ); $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); mongodb-1.3.4/tests/utils/classes.inc0000664000175000017500000000274013210321137017432 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 MongoDB\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.3.4/tests/utils/tools.php0000664000175000017500000003166013210321137017156 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; } } /** * Canonicalizes a JSON string. * * @param string $json * @return string */ function json_canonicalize($json) { $json = json_encode(json_decode($json)); /* Versions of PHP before 7.1 replace empty JSON keys with "_empty_" when * decoding to a stdClass (see: https://bugs.php.net/bug.php?id=46600). Work * around this by replacing "_empty_" keys before returning. */ return str_replace('"_empty_":', '"":', $json); } /** * 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()) { return MongoDB\BSON\toPHP($var, $typemap); } function fromPHP($var) { return MongoDB\BSON\fromPHP($var); } function toJSON($var) { return MongoDB\BSON\toJSON($var); } function toCanonicalExtendedJSON($var) { return MongoDB\BSON\toCanonicalExtendedJSON($var); } function toRelaxedExtendedJSON($var) { return MongoDB\BSON\toRelaxedExtendedJSON($var); } function fromJSON($var) { return MongoDB\BSON\fromJSON($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.3.4/tests/writeConcern/writeconcern-bsonserialize-001.phpt0000664000175000017500000000233213210321137025345 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern::bsonSerialize() --FILE-- 1 new MongoDB\Driver\WriteConcern(-2, 1000), ]; foreach ($tests as $test) { echo toJSON(fromPHP($test)), "\n"; } ?> ===DONE=== --EXPECT-- { "w" : "majority" } { } { "w" : -1 } { "w" : 0 } { "w" : 1 } { "w" : "majority" } { "w" : "tag" } { "w" : 1 } { "w" : 1, "j" : false } { "w" : 1, "wtimeout" : 1000 } { "w" : 1, "j" : true, "wtimeout" : 1000 } { "j" : true } { "wtimeout" : 1000 } ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern-bsonserialize-002.phpt0000664000175000017500000000335713210321137025356 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern::bsonSerialize() returns an object --FILE-- 1 new MongoDB\Driver\WriteConcern(-2, 1000), ]; foreach ($tests as $test) { var_dump($test->bsonSerialize()); } ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["w"]=> string(8) "majority" } object(stdClass)#%d (%d) { } object(stdClass)#%d (%d) { ["w"]=> int(-1) } object(stdClass)#%d (%d) { ["w"]=> int(0) } object(stdClass)#%d (%d) { ["w"]=> int(1) } object(stdClass)#%d (%d) { ["w"]=> string(8) "majority" } object(stdClass)#%d (%d) { ["w"]=> string(3) "tag" } object(stdClass)#%d (%d) { ["w"]=> int(1) } object(stdClass)#%d (%d) { ["w"]=> int(1) ["j"]=> bool(false) } object(stdClass)#%d (%d) { ["w"]=> int(1) ["wtimeout"]=> int(1000) } object(stdClass)#%d (%d) { ["w"]=> int(1) ["j"]=> bool(true) ["wtimeout"]=> int(1000) } object(stdClass)#%d (%d) { ["j"]=> bool(true) } object(stdClass)#%d (%d) { ["wtimeout"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern-constants.phpt0000664000175000017500000000045513210321137024216 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern constants --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- string(8) "majority" ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern-ctor-001.phpt0000664000175000017500000000327713210321137023454 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern construction --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) ["wtimeout"]=> int(2000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(7) "tagname" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["wtimeout"]=> int(3000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["j"]=> bool(true) ["wtimeout"]=> int(4000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["j"]=> bool(false) ["wtimeout"]=> int(5000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["wtimeout"]=> int(6000) } ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern-ctor_error-001.phpt0000664000175000017500000000122313210321137024652 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.3.4/tests/writeConcern/writeconcern-ctor_error-002.phpt0000664000175000017500000000206313210321137024656 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.3.4/tests/writeConcern/writeconcern-ctor_error-003.phpt0000664000175000017500000000073113210321137024657 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.3.4/tests/writeConcern/writeconcern-ctor_error-004.phpt0000664000175000017500000000075113210321137024662 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.3.4/tests/writeConcern/writeconcern-ctor_error-005.phpt0000664000175000017500000000111513210321137024656 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.3.4/tests/writeConcern/writeconcern-debug-001.phpt0000664000175000017500000000123713210321137023565 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) { ["j"]=> bool(true) ["wtimeout"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern-debug-002.phpt0000664000175000017500000000137413210321137023570 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern debug output --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(3) "tag" ["j"]=> bool(false) ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["j"]=> bool(true) ["wtimeout"]=> int(500) } ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern-debug-003.phpt0000664000175000017500000000367713210321137023601 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern debug output --FILE-- 1 new MongoDB\Driver\WriteConcern(-2, 1000), ]; foreach ($tests as $test) { var_dump($test); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" } object(MongoDB\Driver\WriteConcern)#%d (%d) { } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(-1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(0) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(3) "tag" } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["j"]=> bool(false) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["j"]=> bool(true) ["wtimeout"]=> int(1000) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["j"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["wtimeout"]=> int(1000) } ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern-getjournal-001.phpt0000664000175000017500000000110013210321137024636 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.3.4/tests/writeConcern/writeconcern-getw-001.phpt0000664000175000017500000000107113210321137023441 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.3.4/tests/writeConcern/writeconcern-getwtimeout-001.phpt0000664000175000017500000000077313210321137025060 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.3.4/tests/writeConcern/writeconcern-isdefault-001.phpt0000664000175000017500000000464713210321137024467 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern::isDefault() --FILE-- getWriteConcern(), // Cannot test "w=-3" since libmongoc URI parsing expects integers >= -2 (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=-2'))->getWriteConcern(), (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=-1'))->getWriteConcern(), (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=0'))->getWriteConcern(), (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=1'))->getWriteConcern(), (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=2'))->getWriteConcern(), (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=tag'))->getWriteConcern(), (new MongoDB\Driver\Manager('mongodb://127.0.0.1/?w=majority'))->getWriteConcern(), // Cannot test ['w' => null] since an integer or string type is expected (PHPC-887) // Cannot test ['w' => -3] or ['w' => -2] since php_phongo_apply_wc_options_to_uri() expects integers >= -1 (new MongoDB\Driver\Manager(null, ['w' => -1]))->getWriteConcern(), (new MongoDB\Driver\Manager(null, ['w' => 0]))->getWriteConcern(), (new MongoDB\Driver\Manager(null, ['w' => 1]))->getWriteConcern(), (new MongoDB\Driver\Manager(null, ['w' => 2]))->getWriteConcern(), (new MongoDB\Driver\Manager(null, ['w' => 'tag']))->getWriteConcern(), (new MongoDB\Driver\Manager(null, ['w' => 'majority']))->getWriteConcern(), (new MongoDB\Driver\Manager)->getWriteConcern(), ]; foreach ($tests as $wc) { var_dump($wc->isDefault()); } ?> ===DONE=== --EXPECT-- bool(false) bool(true) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(true) bool(true) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(false) bool(true) ===DONE=== mongodb-1.3.4/tests/writeConcern/writeconcern_error-001.phpt0000664000175000017500000000044313210321137023710 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyWriteConcern may not inherit from final class (MongoDB\Driver\WriteConcern) in %s on line %d mongodb-1.3.4/tests/writeConcernError/writeconcernerror-debug-001.phpt0000664000175000017500000000151713210321137025652 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcernError debug output --SKIPIF-- --FILE-- insert(['x' => 1]); try { /* We assume that the replica set does not have 12 nodes */ $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(12)); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcernError)#%d (%d) { ["message"]=> string(29) "Not enough data-bearing nodes" ["code"]=> int(100) ["info"]=> NULL } ===DONE=== mongodb-1.3.4/tests/writeConcernError/writeconcernerror-debug-002.phpt0000664000175000017500000000163513210321137025654 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcernError debug output --SKIPIF-- --FILE-- insert(['x' => $i, 'y' => str_repeat('a', 4194304)]); } try { $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(2, 1)); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcernError)#%d (%d) { ["message"]=> string(33) "waiting for replication timed out" ["code"]=> int(64) ["info"]=> object(stdClass)#%d (%d) { ["wtimeout"]=> bool(true) } } ===DONE=== mongodb-1.3.4/tests/writeConcernError/writeconcernerror-getcode-001.phpt0000664000175000017500000000130213210321137026166 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcernError::getCode() --SKIPIF-- --FILE-- insert(['x' => 1]); try { /* We assume that the replica set does not have 12 nodes */ $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(12)); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()->getCode()); } ?> ===DONE=== --EXPECT-- int(100) ===DONE=== mongodb-1.3.4/tests/writeConcernError/writeconcernerror-getinfo-001.phpt0000664000175000017500000000127613210321137026221 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcernError::getInfo() --SKIPIF-- --FILE-- insert(['x' => 1]); try { /* We assume that the replica set does not have 12 nodes */ $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(12)); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()->getInfo()); } ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeConcernError/writeconcernerror-getinfo-002.phpt0000664000175000017500000000140413210321137026213 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcernError::getInfo() --SKIPIF-- --FILE-- insert(['x' => $i, 'y' => str_repeat('a', 4194304)]); } try { $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(2, 1)); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()->getInfo()); } ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["wtimeout"]=> bool(true) } ===DONE=== mongodb-1.3.4/tests/writeConcernError/writeconcernerror-getmessage-001.phpt0000664000175000017500000000135213210321137026705 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcernError::getMessage() --SKIPIF-- --FILE-- insert(['x' => 1]); try { /* We assume that the replica set does not have 12 nodes */ $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(12)); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()->getMessage()); } ?> ===DONE=== --EXPECT-- string(29) "Not enough data-bearing nodes" ===DONE=== mongodb-1.3.4/tests/writeConcernError/writeconcernerror_error-001.phpt0000664000175000017500000000047413210321137026000 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcernError cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyWriteConcernError may not inherit from final class (MongoDB\Driver\WriteConcernError) in %s on line %d mongodb-1.3.4/tests/writeError/writeerror-debug-001.phpt0000664000175000017500000000156013210321137022770 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteError debug output --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteErrors()[0]); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(95) "E11000 duplicate key error index: phongo.writeError_writeerror_debug_001.$_id_ dup key: { : 1 }" ["code"]=> int(11000) ["index"]=> int(1) ["info"]=> NULL } ===DONE=== mongodb-1.3.4/tests/writeError/writeerror-getCode-001.phpt0000664000175000017500000000122113210321137023246 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteError::getCode() --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteErrors()[0]->getCode()); } ?> ===DONE=== --EXPECT-- int(11000) ===DONE=== mongodb-1.3.4/tests/writeError/writeerror-getIndex-001.phpt0000664000175000017500000000121713210321137023450 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteError::getIndex() --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteErrors()[0]->getIndex()); } ?> ===DONE=== --EXPECT-- int(1) ===DONE=== mongodb-1.3.4/tests/writeError/writeerror-getInfo-001.phpt0000664000175000017500000000133313210321137023273 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteError::getInfo() --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { // "errInfo" is rarely populated on a WriteError (e.g. shard version error) var_dump($e->getWriteResult()->getWriteErrors()[0]->getInfo()); } ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeError/writeerror-getMessage-001.phpt0000664000175000017500000000137713210321137023774 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteError::getMessage() --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch(MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteErrors()[0]->getMessage()); } ?> ===DONE=== --EXPECT-- string(100) "E11000 duplicate key error index: phongo.writeError_writeerror_getMessage_001.$_id_ dup key: { : 1 }" ===DONE=== mongodb-1.3.4/tests/writeError/writeerror_error-001.phpt0000664000175000017500000000043113210321137023111 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteError cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyWriteError may not inherit from final class (MongoDB\Driver\WriteError) in %s on line %d mongodb-1.3.4/tests/writeResult/bug0671-003.phpt0000664000175000017500000000154213210321137020762 0ustar jmikolajmikola--TEST-- PHPC-671: Segfault if Manager is already freed when using WriteResult's Server --SKIPIF-- --FILE-- insert(['_id' => 1]); $writeResult = $manager->executeBulkWrite(NS, $bulk); unset($manager); $server = $writeResult->getServer(); /* WriteResult only uses the client to construct a Server. We need to interact * with the Server to test for a user-after-free. */ $cursor = $server->executeCommand(DATABASE_NAME, new MongoDB\Driver\Command(['ping' => 1])); var_dump($cursor->toArray()[0]); ?> ===DONE=== --EXPECTF-- object(stdClass)#%d (%d) { ["ok"]=> float(1) } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-debug-001.phpt0000664000175000017500000000261013210321137023337 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult debug output without errors --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteResult)#%d (%d) { ["nInserted"]=> int(1) ["nMatched"]=> int(1) ["nModified"]=> int(1) ["nRemoved"]=> int(1) ["nUpserted"]=> int(2) ["upsertedIds"]=> array(2) { [0]=> array(2) { ["index"]=> int(2) ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } } [1]=> array(2) { ["index"]=> int(3) ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } } } ["writeErrors"]=> array(0) { } ["writeConcernError"]=> NULL ["writeConcern"]=> object(MongoDB\Driver\WriteConcern)#%d (%d) { } } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-debug-002.phpt0000664000175000017500000000536113210321137023346 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult debug output with errors --SKIPIF-- --FILE-- false]); $bulk->update(['x' => 1], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 2], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $bulk->insert(['_id' => 3]); try { /* We assume that the replica set does not have 30 nodes */ $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(30)); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteResult)#%d (%d) { ["nInserted"]=> int(3) ["nMatched"]=> int(0) ["nModified"]=> int(0) ["nRemoved"]=> int(0) ["nUpserted"]=> int(2) ["upsertedIds"]=> array(2) { [0]=> array(2) { ["index"]=> int(0) ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } } [1]=> array(2) { ["index"]=> int(1) ["_id"]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } } } ["writeErrors"]=> array(3) { [0]=> object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(108) "E11000 duplicate key error collection: phongo.writeResult_writeresult_debug_002 index: _id_ dup key: { : 1 }" ["code"]=> int(11000) ["index"]=> int(3) ["info"]=> NULL } [1]=> object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(108) "E11000 duplicate key error collection: phongo.writeResult_writeresult_debug_002 index: _id_ dup key: { : 2 }" ["code"]=> int(11000) ["index"]=> int(5) ["info"]=> NULL } [2]=> object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(108) "E11000 duplicate key error collection: phongo.writeResult_writeresult_debug_002 index: _id_ dup key: { : 3 }" ["code"]=> int(11000) ["index"]=> int(7) ["info"]=> NULL } } ["writeConcernError"]=> object(MongoDB\Driver\WriteConcernError)#%d (%d) { ["message"]=> string(29) "Not enough data-bearing nodes" ["code"]=> int(100) ["info"]=> NULL } ["writeConcern"]=> object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(30) } } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getdeletedcount-001.phpt0000664000175000017500000000135413210321137025434 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getDeletedCount() with acknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getDeletedCount()); ?> ===DONE=== --EXPECT-- int(1) ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getdeletedcount-002.phpt0000664000175000017500000000142013210321137025427 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getDeletedCount() with unacknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(0)); var_dump($result->getDeletedCount()); ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getinsertedcount-001.phpt0000664000175000017500000000132613210321137025642 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getInsertedCount() --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getInsertedCount()); ?> ===DONE=== --EXPECT-- int(1) ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getinsertedcount-002.phpt0000664000175000017500000000142213210321137025640 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getInsertedCount() with unacknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(0)); var_dump($result->getInsertedCount()); ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getmatchedcount-001.phpt0000664000175000017500000000132413210321137025430 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getMatchedCount() --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getMatchedCount()); ?> ===DONE=== --EXPECT-- int(1) ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getmatchedcount-002.phpt0000664000175000017500000000142013210321137025426 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getMatchedCount() with unacknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(0)); var_dump($result->getMatchedCount()); ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getmodifiedcount-001.phpt0000664000175000017500000000135613210321137025610 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getModifiedCount() with acknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getModifiedCount()); ?> ===DONE=== --EXPECT-- int(1) ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getmodifiedcount-002.phpt0000664000175000017500000000142213210321137025603 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getModifiedCount() with unacknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(0)); var_dump($result->getModifiedCount()); ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getmodifiedcount-003.phpt0000664000175000017500000000137513210321137025613 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getModifiedCount() not available for legacy writes --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getModifiedCount()); ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getserver-001.phpt0000664000175000017500000000115713210321137024264 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getUpsertedIds() --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY)); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(['x' => 1]); $result = $server->executeBulkWrite(NS, $bulk); var_dump($result->getServer() == $server); ?> ===DONE=== --EXPECT-- bool(true) ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getupsertedcount-001.phpt0000664000175000017500000000135613210321137025663 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getUpsertedCount() with acknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getUpsertedCount()); ?> ===DONE=== --EXPECT-- int(2) ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getupsertedcount-002.phpt0000664000175000017500000000142213210321137025656 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getUpsertedCount() with unacknowledged write --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(0)); var_dump($result->getUpsertedCount()); ?> ===DONE=== --EXPECT-- NULL ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getupsertedids-001.phpt0000664000175000017500000000164613210321137025314 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getUpsertedIds() with server-generated values --SKIPIF-- --FILE-- insert(['x' => 1]); $bulk->update(['x' => 1], ['$set' => ['y' => 3]]); $bulk->update(['x' => 2], ['$set' => ['y' => 1]], ['upsert' => true]); $bulk->update(['x' => 3], ['$set' => ['y' => 2]], ['upsert' => true]); $bulk->delete(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getUpsertedIds()); ?> ===DONE=== --EXPECTF-- array(2) { [2]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } [3]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "%x" } } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getupsertedids-002.phpt0000664000175000017500000000420213210321137025304 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getUpsertedIds() with client-generated values --SKIPIF-- --FILE-- update(['_id' => $value], ['$set' => ['x' => 1]], ['upsert' => true]); } $result = $manager->executeBulkWrite(NS, $bulk); var_dump($result->getUpsertedIds()); ?> ===DONE=== --EXPECTF-- array(13) { [0]=> NULL [1]=> bool(true) [2]=> int(1) [3]=> float(3.14) [4]=> string(3) "foo" [5]=> object(stdClass)#%d (%d) { } [6]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(3) "foo" ["type"]=> int(0) } [7]=> object(MongoDB\BSON\Javascript)#%d (%d) { ["code"]=> string(12) "function(){}" ["scope"]=> NULL } [8]=> object(MongoDB\BSON\MaxKey)#%d (%d) { } [9]=> object(MongoDB\BSON\MinKey)#%d (%d) { } [10]=> object(MongoDB\BSON\ObjectId)#%d (%d) { ["oid"]=> string(24) "586c18d86118fd6c9012dec1" } [11]=> object(MongoDB\BSON\Timestamp)#%d (%d) { ["increment"]=> string(4) "1234" ["timestamp"]=> string(4) "5678" } [12]=> object(MongoDB\BSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> string(13) "1483479256924" } } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getwriteconcernerror-001.phpt0000664000175000017500000000152613210321137026532 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getWriteConcernError() --SKIPIF-- --FILE-- insert(['x' => 1]); try { /* We assume that the replica set does not have 12 nodes */ $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(12)); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteConcernError()); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcernError)#%d (%d) { ["message"]=> string(29) "Not enough data-bearing nodes" ["code"]=> int(100) ["info"]=> NULL } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getwriteerrors-001.phpt0000664000175000017500000000201713210321137025341 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getWriteErrors() with ordered execution --SKIPIF-- --FILE-- insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $bulk->insert(['_id' => 4]); $bulk->insert(['_id' => 4]); try { $result = $manager->executeBulkWrite(NS, $bulk); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteErrors()); } ?> ===DONE=== --EXPECTF-- array(1) { [0]=> object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(%d) "E11000 duplicate key error %s: phongo.writeResult_writeresult_getwriteerrors_001%sdup key: { : 2 }" ["code"]=> int(11000) ["index"]=> int(2) ["info"]=> NULL } } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-getwriteerrors-002.phpt0000664000175000017500000000247013210321137025345 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::getWriteErrors() with unordered execution --SKIPIF-- --FILE-- false]); $bulk->insert(['_id' => 1]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 2]); $bulk->insert(['_id' => 3]); $bulk->insert(['_id' => 4]); $bulk->insert(['_id' => 4]); try { $result = $manager->executeBulkWrite(NS, $bulk); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { var_dump($e->getWriteResult()->getWriteErrors()); } ?> ===DONE=== --EXPECTF-- array(2) { [0]=> object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(%d) "E11000 duplicate key error %s: phongo.writeResult_writeresult_getwriteerrors_002%sdup key: { : 2 }" ["code"]=> int(11000) ["index"]=> int(2) ["info"]=> NULL } [1]=> object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(%d) "E11000 duplicate key error %s: phongo.writeResult_writeresult_getwriteerrors_002%sdup key: { : 4 }" ["code"]=> int(11000) ["index"]=> int(5) ["info"]=> NULL } } ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult-isacknowledged-001.phpt0000664000175000017500000000122213210321137025232 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::isAcknowledged() --SKIPIF-- --FILE-- insert(['x' => 1]); $result = $manager->executeBulkWrite(NS, $bulk, $wc); var_dump($result->isAcknowledged()); } ?> ===DONE=== --EXPECT-- bool(false) bool(true) ===DONE=== mongodb-1.3.4/tests/writeResult/writeresult_error-001.phpt0000664000175000017500000000043613210321137023470 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult cannot be extended --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyWriteResult may not inherit from final class (MongoDB\Driver\WriteResult) in %s on line %d mongodb-1.3.4/CREDITS0000664000175000017500000000010713210321137014013 0ustar jmikolajmikolaMongoDB Driver for PHP Hannes Magnusson, Jeremy Mikola, Derick Rethans mongodb-1.3.4/LICENSE0000664000175000017500000002613713210321137014013 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.3.4/Makefile.frag0000664000175000017500000000530513210321137015356 0ustar jmikolajmikola.PHONY: coverage testclean package package.xml 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;') 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 distcheck" @echo -e "\t - Builds the archive, runs the virtual tests" @echo "" @echo -e "\t$$ make package.xml" @echo -e "\t - Creates a package.xml file with empty release notes" @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 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 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; package: pecl package package.xml package.xml: php bin/prep-release.php $(MONGODB_VERSION) $(MONGODB_STABILITY) mongodb-1.3.4/README.md0000664000175000017500000000452313210321137014260 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 ## 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.3.4/Vagrantfile0000664000175000017500000000765213210321137015174 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.provider "virtualbox" do |virtualbox| virtualbox.memory = 2048 virtualbox.cpus = 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.3.4/config.m40000664000175000017500000005366413210321137014522 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) PHP_ARG_WITH(system-ciphers, whether to use system default cipher list instead of hardcoded value, [ --with-system-ciphers OPENSSL: Use system default cipher list instead of hardcoded value], no, no) dnl borrowed from libmongoc configure.ac dnl AS_VAR_COPY is available in AC 2.64 and on, but we only require 2.60. dnl If we're on an older version, we define it ourselves: m4_ifndef([AS_VAR_COPY], [m4_define([AS_VAR_COPY], [AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])])]) dnl Get "user-set cflags" here, before we've added the flags we use by default AS_VAR_COPY(MONGOC_USER_SET_CFLAGS, [CFLAGS]) AC_SUBST(MONGOC_USER_SET_CFLAGS) AS_VAR_COPY(MONGOC_USER_SET_LDFLAGS, [LDFLAGS]) AC_SUBST(MONGOC_USER_SET_LDFLAGS) AS_VAR_COPY(MONGOC_CC, [CC]) AC_SUBST(MONGOC_CC) 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 AC_SUBST(BSON_BYTE_ORDER, 4321) else AC_SUBST(BSON_BYTE_ORDER, 1234) fi ]) 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 AC_SUBST(BSON_HAVE_CLOCK_GETTIME, 1) fi ]) 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") PHP_CHECK_GCC_ARG(-Werror, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Werror") PHP_CHECK_GCC_ARG(-Wextra, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wextra") PHP_CHECK_GCC_ARG(-Wno-unused-parameter, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-unused-parameter") PHP_CHECK_GCC_ARG(-Wno-unused-but-set-variable, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-unused-but-set-variable") PHP_CHECK_GCC_ARG(-Wno-missing-field-initializers, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-missing-field-initializers") MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS" STD_CFLAGS="-g -O0 -Wall" 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 PHP_MONGODB_CFLAGS="$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS" PHP_MONGODB_SOURCES="\ php_phongo.c \ phongo_compat.c \ src/bson.c \ src/bson-encode.c \ src/BSON/Binary.c \ src/BSON/BinaryInterface.c \ src/BSON/Decimal128.c \ src/BSON/Decimal128Interface.c \ src/BSON/Javascript.c \ src/BSON/JavascriptInterface.c \ src/BSON/MaxKey.c \ src/BSON/MaxKeyInterface.c \ src/BSON/MinKey.c \ src/BSON/MinKeyInterface.c \ src/BSON/ObjectId.c \ src/BSON/ObjectIdInterface.c \ src/BSON/Persistable.c \ src/BSON/Regex.c \ src/BSON/RegexInterface.c \ src/BSON/Serializable.c \ src/BSON/Timestamp.c \ src/BSON/TimestampInterface.c \ src/BSON/Type.c \ src/BSON/Unserializable.c \ src/BSON/UTCDateTime.c \ src/BSON/UTCDateTimeInterface.c \ src/BSON/functions.c \ src/MongoDB/BulkWrite.c \ 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/WriteConcern.c \ src/MongoDB/WriteConcernError.c \ src/MongoDB/WriteError.c \ src/MongoDB/WriteResult.c \ src/MongoDB/Exception/AuthenticationException.c \ src/MongoDB/Exception/BulkWriteException.c \ src/MongoDB/Exception/ConnectionException.c \ src/MongoDB/Exception/ConnectionTimeoutException.c \ src/MongoDB/Exception/Exception.c \ src/MongoDB/Exception/ExecutionTimeoutException.c \ src/MongoDB/Exception/InvalidArgumentException.c \ src/MongoDB/Exception/LogicException.c \ src/MongoDB/Exception/RuntimeException.c \ src/MongoDB/Exception/SSLConnectionException.c \ src/MongoDB/Exception/UnexpectedValueException.c \ src/MongoDB/Exception/WriteException.c \ src/MongoDB/Monitoring/CommandFailedEvent.c \ src/MongoDB/Monitoring/CommandStartedEvent.c \ src/MongoDB/Monitoring/CommandSubscriber.c \ src/MongoDB/Monitoring/CommandSucceededEvent.c \ src/MongoDB/Monitoring/Subscriber.c \ src/MongoDB/Monitoring/functions.c \ " PHP_ARG_WITH(libbson, whether to use system libbson, [ --with-libbson Use system libbson], no, no) PHP_ARG_WITH(libmongoc, whether to use system libmongoc, [ --with-libmongoc Use system libmongoc], no, no) if test "$PHP_LIBBSON" != "no"; then if test "$PHP_LIBMONGOC" == "no"; then AC_MSG_ERROR(Cannot use system libbson and bundled libmongoc) fi 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.8.0; 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.8.0) 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_MONGODB_BSON_CFLAGS="$STD_CFLAGS -DBSON_COMPILATION" dnl Generated with: find src/libbson/src/bson -name '*.c' -print0 | cut -sz -d / -f 5- | sort -z | tr '\000' ' ' PHP_MONGODB_BSON_SOURCES="bcon.c bson-atomic.c bson.c bson-clock.c bson-context.c bson-decimal128.c bson-error.c bson-iso8601.c bson-iter.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" dnl Generated with: find src/libbson/src/jsonsl -name '*.c' -print0 | cut -sz -d / -f 5- | sort -z | tr '\000' ' ' PHP_MONGODB_JSONSL_SOURCES="jsonsl.c" PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libbson/src/bson], $PHP_MONGODB_BSON_SOURCES, $PHP_MONGODB_BSON_CFLAGS, shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libbson/src/jsonsl], $PHP_MONGODB_JSONSL_SOURCES, $PHP_MONGODB_BSON_CFLAGS, shared_objects_mongodb, yes) fi AC_MSG_CHECKING(configuring libmongoc) AC_MSG_RESULT(...) if test "$PHP_LIBMONGOC" != "no"; then if test "$PHP_LIBBSON" == "no"; then AC_MSG_ERROR(Cannot use system libmongoc and bundled libbson) fi AC_PATH_PROG(PKG_CONFIG, pkg-config, no) AC_MSG_CHECKING(for libmongoc) if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmongoc-1.0; then if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.8.0; then LIBMONGOC_INC=`$PKG_CONFIG libmongoc-1.0 --cflags` LIBMONGOC_LIB=`$PKG_CONFIG libmongoc-1.0 --libs` LIBMONGOC_VER=`$PKG_CONFIG libmongoc-1.0 --modversion` AC_MSG_RESULT(version $LIBMONGOC_VER found) else AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.8.0) 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 PHP_MONGODB_MONGOC_CFLAGS="$STD_CFLAGS -DMONGOC_COMPILATION -DMONGOC_TRACE" dnl Generated with: find src/libmongoc/src/mongoc -name '*.c' -print0 | cut -sz -d / -f 5- | sort -z | tr '\000' ' ' PHP_MONGODB_MONGOC_SOURCES="mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-b64.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-client.c mongoc-client-pool.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-gssapi.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-cursorid.c mongoc-cursor-transform.c mongoc-cyrus.c mongoc-database.c mongoc-find-and-modify.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-gssapi.c mongoc-handshake.c mongoc-host-list.c mongoc-index.c mongoc-init.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-openssl.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-description.c mongoc-server-stream.c mongoc-set.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-concern.c" PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libmongoc/src/mongoc], $PHP_MONGODB_MONGOC_SOURCES, $PHP_MONGODB_MONGOC_CFLAGS, shared_objects_mongodb, yes) AC_SUBST(MONGOC_ENABLE_CRYPTO, 0) AC_SUBST(MONGOC_ENABLE_SSL, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 0) AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 0) AC_SUBST(MONGOC_HAVE_ASN1_STRING_GET0_DATA, 0) PHP_SETUP_OPENSSL(MONGODB_SHARED_LIBADD, [ AC_SUBST(MONGOC_ENABLE_CRYPTO, 1) AC_SUBST(MONGOC_ENABLE_SSL, 1) AC_SUBST(MONGOC_ENABLE_CRYPTO_LIBCRYPTO, 1) AC_SUBST(MONGOC_ENABLE_SSL_OPENSSL, 1) ]) if test "$PHP_SYSTEM_CIPHERS" != "no"; then AC_SUBST(MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE, 1) else AC_SUBST(MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE, 0) fi dnl TODO: Support building with Secure Transport on OSX AC_SUBST(MONGOC_ENABLE_SSL_SECURE_TRANSPORT, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO, 0) dnl Secure Channel only applies to Windows AC_SUBST(MONGOC_ENABLE_SSL_SECURE_CHANNEL, 0) AC_SUBST(MONGOC_ENABLE_CRYPTO_CNG, 0) AC_SUBST(MONGOC_ENABLE_SSL_LIBRESSL, 0) AC_SUBST(MONGOC_NO_AUTOMATIC_GLOBALS, 1) AC_CHECK_TYPE([socklen_t], [AC_SUBST(MONGOC_HAVE_SOCKLEN, 1)], [AC_SUBST(MONGOC_HAVE_SOCKLEN, 0)], [#include ]) AC_SUBST(MONGOC_ENABLE_COMPRESSION_SNAPPY, 0) AC_SUBST(MONGOC_ENABLE_COMPRESSION_ZLIB, 0) AC_SUBST(MONGOC_ENABLE_COMPRESSION, 0) fi PHP_ARG_WITH(mongodb-sasl, for Cyrus SASL support, [ --with-mongodb-sasl[=DIR] mongodb: Include Cyrus SASL support], auto, no) AC_SUBST(MONGOC_ENABLE_SASL, 0) AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) AC_SUBST(MONGOC_ENABLE_SASL_CYRUS, 0) AC_SUBST(MONGOC_ENABLE_SASL_SSPI, 0) AC_SUBST(MONGOC_ENABLE_SASL_GSSAPI, 0) 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!]) 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) AC_SUBST(MONGOC_ENABLE_SASL, 1) AC_SUBST(MONGOC_ENABLE_SASL_CYRUS, 1) ], [ if test "$MONGODB_SASL" != "auto"; then AC_MSG_ERROR([MongoDB 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) ]) fi fi m4_include(src/libmongoc/build/autotools/m4/ax_prototype.m4) m4_include(src/libmongoc/build/autotools/CheckCompiler.m4) 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" 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) PHP_NEW_EXTENSION(mongodb, $PHP_MONGODB_SOURCES, $ext_shared,, $PHP_MONGODB_CFLAGS) PHP_ADD_EXTENSION_DEP(mongodb, date) PHP_ADD_EXTENSION_DEP(mongodb, json) PHP_ADD_EXTENSION_DEP(mongodb, spl) PHP_ADD_EXTENSION_DEP(mongodb, standard) 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/MongoDB/Monitoring/]) 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/MongoDB/Monitoring/]) 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/jsonsl/]) 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/jsonsl/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/libbson/src/bson/]) fi PHP_BSON_BIGENDIAN AC_HEADER_STDBOOL AC_SUBST(BSON_EXTRA_ALIGN, 0) AC_SUBST(BSON_HAVE_DECIMAL128, 0) if test "$ac_cv_header_stdbool_h" = "yes"; then AC_SUBST(BSON_HAVE_STDBOOL_H, 1) else AC_SUBST(BSON_HAVE_STDBOOL_H, 0) fi AC_SUBST(BSON_OS, 1) 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 AC_SUBST(BSON_HAVE_STRNLEN, 1) else AC_SUBST(BSON_HAVE_STRNLEN, 0) fi AC_CHECK_FUNC(snprintf,ac_cv_func_snprintf=yes,ac_cv_func_snprintf=no) if test "$ac_cv_func_snprintf" = "yes"; then AC_SUBST(BSON_HAVE_SNPRINTF, 1) else AC_SUBST(BSON_HAVE_SNPRINTF, 0) fi 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.3.4/config.w320000664000175000017500000002605613210321137014610 0ustar jmikolajmikola// vim:ft=javascript function mongodb_generate_header(inpath, outpath, replacements) { STDOUT.WriteLine("Generating " + outpath); var infile = FSO.OpenTextFile(inpath, 1); var outdata = infile.ReadAll(); infile.Close(); for (var key in replacements) { var replacement = replacements[key]; if (typeof replacement === 'string') { replacement = replacement.replace(/"/g, '\\"'); } outdata = outdata.replace(new RegExp('@' + key + '@', 'g'), replacement); } var outfile = FSO.CreateTextFile(outpath, true); outfile.Write(outdata); outfile.Close(); } function mongodb_parse_version_file(inpath, prefix) { var infile = FSO.OpenTextFile(inpath, 1); var version = infile.ReadLine(); infile.Close(); var xyz_pre = version.split("-"); var xyz = xyz_pre[0].split("."); var pre = xyz_pre.length > 1 ? xyz_pre[1] : ""; var replacements = {}; replacements[prefix + "VERSION"] = version; replacements[prefix + "MAJOR_VERSION"] = xyz[0]; replacements[prefix + "MINOR_VERSION"] = xyz[1]; replacements[prefix + "MICRO_VERSION"] = xyz[2]; replacements[prefix + "PRERELEASE_VERSION"] = pre; return replacements; } ARG_ENABLE("mongodb", "MongoDB support", "no"); ARG_WITH("mongodb-sasl", "MongoDB: Build against Cyrus-SASL", "yes"); if (PHP_MONGODB != "no") { /* Note: ADD_EXTENSION_DEP() cannot be used to declare that we depend on the * date and standard extensions. Assume that they're always enabled. */ ADD_EXTENSION_DEP("mongodb", "json", false); ADD_EXTENSION_DEP("mongodb", "spl", false); /* MongoDB does not actually depend on PHP's OpenSSL extension, but this is in * place to ensure that later SSL library checks succeed. This can be removed * once we support building with Secure Channel. */ ADD_EXTENSION_DEP("mongodb", "openssl", false); var PHP_MONGODB_CFLAGS="\ /D BSON_COMPILATION /D MONGOC_COMPILATION /D MONGOC_TRACE \ /I" + configure_module_dirname + " \ /I" + configure_module_dirname + "/src/BSON \ /I" + configure_module_dirname + "/src/MongoDB \ /I" + configure_module_dirname + "/src/MongoDB/Exception \ /I" + configure_module_dirname + "/src/contrib \ /I" + configure_module_dirname + "/src/libbson/src \ /I" + configure_module_dirname + "/src/libbson/src/bson \ /I" + configure_module_dirname + "/src/libbson/src/yajl \ /I" + configure_module_dirname + "/src/libmongoc/src/mongoc \ "; // Condense whitespace in CFLAGS PHP_MONGODB_CFLAGS = PHP_MONGODB_CFLAGS.replace(/\s+/g, ' '); // Generated with: find src/libbson/src/bson -name '*.c' -print0 | cut -sz -d / -f 5- | sort -z | tr '\000' ' ' var PHP_MONGODB_BSON_SOURCES="bcon.c bson-atomic.c bson.c bson-clock.c bson-context.c bson-decimal128.c bson-error.c bson-iso8601.c bson-iter.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"; // Generated with: find src/libbson/src/jsonsl -name '*.c' -print0 | cut -sz -d / -f 5- | sort -z | tr '\000' ' ' var PHP_MONGODB_JSONSL_SOURCES="jsonsl.c"; // Generated with: find src/libmongoc/src/mongoc -name '*.c' -print0 | cut -sz -d / -f 4- | sort -z | tr '\000' ' ' var PHP_MONGODB_MONGOC_SOURCES="mongoc-apm.c mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-b64.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-client.c mongoc-client-pool.c mongoc-cluster.c mongoc-cluster-cyrus.c mongoc-cluster-gssapi.c mongoc-cluster-sasl.c mongoc-cluster-sspi.c mongoc-cmd.c mongoc-collection.c mongoc-compression.c mongoc-counters.c mongoc-crypto.c mongoc-crypto-cng.c mongoc-crypto-common-crypto.c mongoc-crypto-openssl.c mongoc-cursor-array.c mongoc-cursor.c mongoc-cursor-cursorid.c mongoc-cursor-transform.c mongoc-cyrus.c mongoc-database.c mongoc-find-and-modify.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-list.c mongoc-gridfs-file-page.c mongoc-gssapi.c mongoc-handshake.c mongoc-host-list.c mongoc-index.c mongoc-init.c mongoc-libressl.c mongoc-linux-distro-scanner.c mongoc-list.c mongoc-log.c mongoc-matcher.c mongoc-matcher-op.c mongoc-memcmp.c mongoc-openssl.c mongoc-queue.c mongoc-rand-cng.c mongoc-rand-common-crypto.c mongoc-rand-openssl.c mongoc-read-concern.c mongoc-read-prefs.c mongoc-rpc.c mongoc-sasl.c mongoc-scram.c mongoc-secure-channel.c mongoc-secure-transport.c mongoc-server-description.c mongoc-server-stream.c mongoc-set.c mongoc-socket.c mongoc-ssl.c mongoc-sspi.c mongoc-stream-buffered.c mongoc-stream.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-socket.c mongoc-stream-tls.c mongoc-stream-tls-libressl.c mongoc-stream-tls-openssl-bio.c mongoc-stream-tls-openssl.c mongoc-stream-tls-secure-channel.c mongoc-stream-tls-secure-transport.c mongoc-topology.c mongoc-topology-description-apm.c mongoc-topology-description.c mongoc-topology-scanner.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-concern.c"; EXTENSION("mongodb", "php_phongo.c phongo_compat.c", null, PHP_MONGODB_CFLAGS); ADD_SOURCES(configure_module_dirname + "/src", "bson.c bson-encode.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/BSON", "Binary.c BinaryInterface.c Decimal128.c Decimal128Interface.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Timestamp.c TimestampInterface.c Type.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "BulkWrite.c Command.c Cursor.c CursorId.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c ConnectionException.c ConnectionTimeoutException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c Subscriber.c functions.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libbson/src/bson", PHP_MONGODB_BSON_SOURCES, "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libbson/src/jsonsl", PHP_MONGODB_JSONSL_SOURCES, "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", PHP_MONGODB_MONGOC_SOURCES, "mongodb"); var bson_opts = { BSON_BYTE_ORDER: 1234, BSON_OS: 2, BSON_HAVE_STDBOOL_H: 0, BSON_HAVE_ATOMIC_32_ADD_AND_FETCH: 0, BSON_HAVE_ATOMIC_64_ADD_AND_FETCH: 0, BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES: 0, BSON_HAVE_CLOCK_GETTIME: 0, BSON_HAVE_STRNLEN: 0, BSON_HAVE_SNPRINTF: 0, BSON_HAVE_REALLOCF: 0, BSON_NEEDS_SET_OUTPUT_FORMAT: 0, BSON_HAVE_TIMESPEC: 0, BSON_EXTRA_ALIGN: 0, BSON_HAVE_SYSCALL_TID: 0, BSON_HAVE_DECIMAL128: 0, BSON_HAVE_GMTIME_R: 0 }; if (CHECK_FUNC_IN_HEADER("stdio.h", "_set_output_format")) { bson_opts.BSON_NEEDS_SET_OUTPUT_FORMAT = 1; } mongodb_generate_header( configure_module_dirname + "/src/libbson/src/bson/bson-config.h.in", configure_module_dirname + "/src/libbson/src/bson/bson-config.h", bson_opts ); mongodb_generate_header( configure_module_dirname + "/src/libbson/src/bson/bson-version.h.in", configure_module_dirname + "/src/libbson/src/bson/bson-version.h", mongodb_parse_version_file(configure_module_dirname + "/src/libbson/VERSION_CURRENT", "BSON_") ); var mongoc_opts = { // TODO: Support building with Secure Channel on Windows MONGOC_ENABLE_SSL_SECURE_CHANNEL: 0, MONGOC_ENABLE_CRYPTO_CNG: 0, // Secure Transport does not apply to Windows MONGOC_ENABLE_SSL_SECURE_TRANSPORT: 0, MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO: 0, MONGOC_ENABLE_SSL_LIBRESSL: 0, MONGOC_ENABLE_SSL_OPENSSL: 0, MONGOC_ENABLE_CRYPTO_LIBCRYPTO: 0, MONGOC_ENABLE_SSL: 0, MONGOC_ENABLE_CRYPTO: 0, MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE: 0, MONGOC_ENABLE_COMPRESSION_SNAPPY: 0, MONGOC_ENABLE_COMPRESSION_ZLIB: 0, MONGOC_ENABLE_COMPRESSION: 0, MONGOC_ENABLE_SASL: 0, MONGOC_ENABLE_SASL_CYRUS: 0, MONGOC_ENABLE_SASL_GSSAPI: 0, MONGOC_ENABLE_SASL_SSPI: 0, MONGOC_HAVE_ASN1_STRING_GET0_DATA: 0, MONGOC_HAVE_SASL_CLIENT_DONE: 0, MONGOC_HAVE_SOCKLEN: 1, MONGOC_HAVE_WEAK_SYMBOLS: 0, MONGOC_NO_AUTOMATIC_GLOBALS: 1, MONGOC_SOCKET_ARG2: "struct sockaddr", MONGOC_SOCKET_ARG3: "socklen_t", MONGOC_CC: "", MONGOC_USER_SET_CFLAGS: "", MONGOC_USER_SET_LDFLAGS: "" }; var mongoc_ssl_path_to_check = PHP_MONGODB; if (typeof PHP_OPENSSL === 'string') { mongoc_ssl_path_to_check += ";" + PHP_OPENSSL; } var mongoc_ssl_found = false; /* PHP 7.1.2 introduced SETUP_OPENSSL(), which supports OpenSSL 1.1.x. Earlier * versions will use the legacy check for OpenSSL 1.0.x and lower. */ if (typeof SETUP_OPENSSL === 'function') { mongoc_ssl_found = SETUP_OPENSSL("mongodb", mongoc_ssl_path_to_check) > 0; } else if (CHECK_LIB("ssleay32.lib", "mongodb", mongoc_ssl_path_to_check) && CHECK_LIB("libeay32.lib", "mongodb", mongoc_ssl_path_to_check) && CHECK_LIB("crypt32.lib", "mongodb", mongoc_ssl_path_to_check) && CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", "CFLAGS_MONGODB")) { mongoc_ssl_found = true; } if (mongoc_ssl_found) { mongoc_opts.MONGOC_ENABLE_SSL_OPENSSL = 1; mongoc_opts.MONGOC_ENABLE_CRYPTO_LIBCRYPTO = 1; mongoc_opts.MONGOC_ENABLE_SSL = 1; mongoc_opts.MONGOC_ENABLE_CRYPTO = 1; } else { WARNING("mongodb libopenssl support not enabled, libs not found"); } // TODO: Support building with native GSSAPI (SSPI) on Windows if (PHP_MONGODB_SASL != "no" && CHECK_LIB("libsasl.lib", "mongodb", PHP_MONGODB) && CHECK_HEADER_ADD_INCLUDE("sasl/sasl.h", "CFLAGS_MONGODB")) { mongoc_opts.MONGOC_ENABLE_SASL = 1; mongoc_opts.MONGOC_ENABLE_SASL_CYRUS = 1; if (CHECK_FUNC_IN_HEADER("sasl/sasl.h", "sasl_client_done")) { mongoc_opts.MONGOC_HAVE_SASL_CLIENT_DONE = 1; } } else { WARNING("mongodb libsasl support not enabled, libs not found"); } if (typeof COMPILER_NAME === 'string') { mongoc_opts.MONGOC_CC = COMPILER_NAME; } else if (typeof VC_VERSIONS[VCVERS] === 'string') { mongoc_opts.MONGOC_CC = VC_VERSIONS[VCVERS]; } /* MONGOC_USER_SET_CFLAGS and MONGOC_USER_SET_LDFLAGS can be left blank, as we * do not expect CFLAGS or LDFLAGS to be customized at build time. */ mongodb_generate_header( configure_module_dirname + "/src/libmongoc/src/mongoc/mongoc-config.h.in", configure_module_dirname + "/src/libmongoc/src/mongoc/mongoc-config.h", mongoc_opts ); mongodb_generate_header( configure_module_dirname + "/src/libmongoc/src/mongoc/mongoc-version.h.in", configure_module_dirname + "/src/libmongoc/src/mongoc/mongoc-version.h", mongodb_parse_version_file(configure_module_dirname + "/src/libmongoc/VERSION_CURRENT", "MONGOC_") ); } mongodb-1.3.4/phongo_compat.c0000664000175000017500000000225013210321137015775 0ustar jmikolajmikola/* * Copyright 2015-2017 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. */ /* Our Compatability header */ #include "phongo_compat.h" 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.3.4/phongo_compat.h0000664000175000017500000001575413210321137016017 0ustar jmikolajmikola/* * Copyright 2015-2017 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 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 >= 70000 # define str_efree(s) efree((char*)s) #else # include #endif #if defined(__GNUC__) # define ARG_UNUSED __attribute__ ((unused)) #else # define ARG_UNUSED #endif #if PHP_VERSION_ID >= 70000 # define phongo_char zend_string # 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_create_object_retval zend_object* # define phongo_get_gc_table zval ** # 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 ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRL(_key), (char *)(_value)); # define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRL(_key), (char *)(_value), _len); # define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len, (char *)(_value), _value_len); # define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRL(_key), _value); # 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_NEXT_INDEX_STRINGL(_zv, _value, _len) add_next_index_stringl(_zv, _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_RETVAL_STRING(s) RETVAL_STRING(s) # define PHONGO_RETURN_STRING(s) RETURN_STRING(s) # define PHONGO_RETVAL_SMART_STR(val) PHONGO_RETVAL_STRINGL(ZSTR_VAL((val).s), ZSTR_LEN((val).s)); #else # define phongo_char char # define phongo_long long # define PHONGO_LONG_FORMAT "ld" # define SIZEOF_PHONGO_LONG SIZEOF_LONG # define ZSTR_VAL(str) str # define phongo_create_object_retval zend_object_value # define phongo_get_gc_table zval *** # 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 ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRS(_key), (char *)(_value), 1); # define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRS(_key), (char *)(_value), _len, 1); # define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len+1, (char *)(_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_NEXT_INDEX_STRINGL(_zv, _value, _len) add_next_index_stringl(_zv, _value, _len, 1); # define Z_PHPDATE_P(object) ((php_date_obj*)zend_object_store_get_object(object TSRMLS_CC)) # define Z_ISUNDEF(x) !x # define ZVAL_UNDEF(x) do { (*x) = NULL; } while (0) # define phongo_free_object_arg void # define phongo_zpp_char_len int # define ZEND_HASH_APPLY_PROTECTION(ht) true # define ZEND_HASH_GET_APPLY_COUNT(ht) ((ht)->nApplyCount) # define ZEND_HASH_DEC_APPLY_COUNT(ht) ((ht)->nApplyCount -= 1) # define ZEND_HASH_INC_APPLY_COUNT(ht) ((ht)->nApplyCount += 1) # define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen, 1) # define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen, 1) # define PHONGO_RETVAL_STRING(s) RETVAL_STRING(s, 1) # define PHONGO_RETURN_STRING(s) RETURN_STRING(s, 1) # define PHONGO_RETVAL_SMART_STR(val) PHONGO_RETVAL_STRINGL((val).c, (val).len); #endif #if SIZEOF_PHONGO_LONG == 8 # define ADD_INDEX_INT64(zval, index, value) add_index_long(zval, index, value) # define ADD_NEXT_INDEX_INT64(zval, value) add_next_index_long(zval, 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) { \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", value); \ } else { \ add_index_long(zval, index, value); \ } # define ADD_NEXT_INDEX_INT64(zval, value) \ if (value > INT32_MAX || value < INT32_MIN) { \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", value); \ } else { \ add_next_index_long(zval, value); \ } # define ADD_ASSOC_INT64(zval, key, value) \ if (value > INT32_MAX || value < INT32_MIN) { \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Integer overflow detected on your platform: %lld", value); \ } else { \ add_assoc_long(zval, key, value); \ } #else # error Unsupported architecture (integers are neither 32-bit nor 64-bit) #endif 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.3.4/php_bson.h0000664000175000017500000000523613210321137014764 0ustar jmikolajmikola/* * Copyright 2014-2017 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 PHONGO_BSON_H #define PHONGO_BSON_H #include /* PHP Core stuff */ #include #define BSON_UNSERIALIZE_FUNC_NAME "bsonUnserialize" #define BSON_SERIALIZE_FUNC_NAME "bsonSerialize" #define PHONGO_ODM_FIELD_NAME "__pclass" 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; bool is_visiting_array; } 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, 0 } #else #define PHONGO_BSON_STATE_INITIALIZER { NULL, { PHONGO_TYPEMAP_NONE, NULL, PHONGO_TYPEMAP_NONE, NULL, PHONGO_TYPEMAP_NONE, NULL }, NULL, 0 } #endif void php_phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson, bson_t **bson_out TSRMLS_DC); bool php_phongo_bson_to_zval_ex(const unsigned char *data, int data_len, php_phongo_bson_state *state); #if PHP_VERSION_ID >= 70000 bool php_phongo_bson_to_zval(const unsigned char *data, int data_len, zval *out); #else bool php_phongo_bson_to_zval(const unsigned char *data, int data_len, zval **out); #endif bool php_phongo_bson_typemap_to_state(zval *typemap, php_phongo_bson_typemap *map TSRMLS_DC); #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.3.4/php_phongo.c0000664000175000017500000024112713210321137015311 0ustar jmikolajmikola/* * Copyright 2014-2017 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 HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include "bson.h" #include "mongoc.h" /* PHP Core stuff */ #include #include #include #include #include #include #include #include #include #include #if PHP_VERSION_ID >= 70000 # include #else # include #endif /* getpid() */ #if HAVE_UNISTD_H # include #endif #ifdef PHP_WIN32 # include #endif /* 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" /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include "src/BSON/functions.h" #include "src/MongoDB/Monitoring/functions.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "PHONGO" #define PHONGO_DEBUG_INI "mongodb.debug" #define PHONGO_DEBUG_INI_DEFAULT "" ZEND_DECLARE_MODULE_GLOBALS(mongodb) #if PHP_VERSION_ID >= 70000 #if defined(ZTS) && defined(COMPILE_DL_MONGODB) ZEND_TSRMLS_CACHE_DEFINE(); #endif #endif /* Declare zend_class_entry dependencies, which are initialized in MINIT */ zend_class_entry *php_phongo_date_immutable_ce; zend_class_entry *php_phongo_json_serializable_ce; php_phongo_server_description_type_map_t php_phongo_server_description_type_map[PHONGO_SERVER_DESCRIPTION_TYPES] = { { PHONGO_SERVER_UNKNOWN, "Unknown" }, { PHONGO_SERVER_STANDALONE, "Standalone" }, { PHONGO_SERVER_MONGOS, "Mongos" }, { PHONGO_SERVER_POSSIBLE_PRIMARY, "PossiblePrimary" }, { PHONGO_SERVER_RS_PRIMARY, "RSPrimary" }, { PHONGO_SERVER_RS_SECONDARY, "RSSecondary" }, { PHONGO_SERVER_RS_ARBITER, "RSArbiter" }, { PHONGO_SERVER_RS_OTHER, "RSOther" }, { PHONGO_SERVER_RS_GHOST, "RSGhost" }, }; /* {{{ phongo_std_object_handlers */ zend_object_handlers phongo_std_object_handlers; zend_object_handlers *phongo_get_std_object_handlers(void) { return &phongo_std_object_handlers; } /* }}} */ /* Forward declarations */ static bool phongo_split_namespace(const char *namespace, char **dbname, char **cname); /* {{{ 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_COMMAND_INVALID_ARG: return php_phongo_invalidargumentexception_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_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_char *dt; PHONGO_TSRMLS_FETCH_FROM_CTX(user_data); (void)user_data; dt = php_format_date((char *) ZEND_STRL("Y-m-d\\TH:i:sP"), time(NULL), 0 TSRMLS_CC); fprintf(MONGODB_G(debug_fd), "[%s] %10s: %-8s> %s\n", ZSTR_VAL(dt), log_domain, mongoc_log_level_str(log_level), message); fflush(MONGODB_G(debug_fd)); efree(dt); } /* }}} */ /* {{{ Init objects */ static void phongo_cursor_init(zval *return_value, mongoc_client_t *client, mongoc_cursor_t *cursor, zval *readPreference 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; if (readPreference) { #if PHP_VERSION_ID >= 70000 ZVAL_ZVAL(&intern->read_preference, readPreference, 1, 0); #else Z_ADDREF_P(readPreference); intern->read_preference = readPreference; #endif } } /* }}} */ static void phongo_cursor_init_for_command(zval *return_value, mongoc_client_t *client, mongoc_cursor_t *cursor, const char *db, zval *command, zval *readPreference TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *intern; phongo_cursor_init(return_value, client, cursor, readPreference TSRMLS_CC); intern = Z_CURSOR_OBJ_P(return_value); intern->database = estrdup(db); #if PHP_VERSION_ID >= 70000 ZVAL_ZVAL(&intern->command, command, 1, 0); #else Z_ADDREF_P(command); intern->command = command; #endif } /* }}} */ static void phongo_cursor_init_for_query(zval *return_value, mongoc_client_t *client, mongoc_cursor_t *cursor, const char *namespace, zval *query, zval *readPreference TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *intern; phongo_cursor_init(return_value, client, cursor, readPreference TSRMLS_CC); intern = Z_CURSOR_OBJ_P(return_value); /* namespace has already been validated by phongo_execute_query() */ phongo_split_namespace(namespace, &intern->database, &intern->collection); #if PHP_VERSION_ID >= 70000 ZVAL_ZVAL(&intern->query, query, 1, 0); #else Z_ADDREF_P(query); intern->query = query; #endif } /* }}} */ 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->server_id = server_id; server->client = client; } /* }}} */ 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); } /* }}} */ zend_bool phongo_writeconcernerror_init(zval *return_value, bson_t *bson TSRMLS_DC) /* {{{ */ { bson_iter_t iter; php_phongo_writeconcernerror_t *intern; object_init_ex(return_value, php_phongo_writeconcernerror_ce); intern = Z_WRITECONCERNERROR_OBJ_P(return_value); if (bson_iter_init_find(&iter, bson, "code") && BSON_ITER_HOLDS_INT32(&iter)) { intern->code = bson_iter_int32(&iter); } if (bson_iter_init_find(&iter, bson, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) { uint32_t errmsg_len; const char *err_msg = bson_iter_utf8(&iter, &errmsg_len); intern->message = estrndup(err_msg, errmsg_len); } if (bson_iter_init_find(&iter, bson, "errInfo") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { uint32_t len; const uint8_t *data = NULL; bson_iter_document(&iter, &len, &data); if (!php_phongo_bson_to_zval(data, len, &intern->info)) { zval_ptr_dtor(&intern->info); ZVAL_UNDEF(&intern->info); 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 *intern; object_init_ex(return_value, php_phongo_writeerror_ce); intern = Z_WRITEERROR_OBJ_P(return_value); if (bson_iter_init_find(&iter, bson, "code") && BSON_ITER_HOLDS_INT32(&iter)) { intern->code = bson_iter_int32(&iter); } if (bson_iter_init_find(&iter, bson, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) { uint32_t errmsg_len; const char *err_msg = bson_iter_utf8(&iter, &errmsg_len); intern->message = estrndup(err_msg, errmsg_len); } if (bson_iter_init_find(&iter, bson, "errInfo") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { uint32_t len; const uint8_t *data = NULL; bson_iter_document(&iter, &len, &data); if (!php_phongo_bson_to_zval(data, len, &intern->info)) { zval_ptr_dtor(&intern->info); ZVAL_UNDEF(&intern->info); return false; } } if (bson_iter_init_find(&iter, bson, "index") && BSON_ITER_HOLDS_INT32(&iter)) { intern->index = bson_iter_int32(&iter); } return true; } /* }}} */ static php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, bson_t *reply, 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->reply = bson_copy(reply); writeresult->server_id = server_id; writeresult->client = client; return writeresult; } /* }}} */ /* }}} */ /* {{{ CRUD */ /* Splits a namespace name into the database and collection names, allocated with estrdup. */ static 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); } /* }}} */ bool phongo_execute_write(mongoc_client_t *client, const char *namespace, php_phongo_bulkwrite_t *bulk_write, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */ { bson_error_t error; int success; bson_t reply = BSON_INITIALIZER; mongoc_bulk_operation_t *bulk = bulk_write->bulk; php_phongo_writeresult_t *writeresult; if (bulk_write->executed) { phongo_throw_exception(PHONGO_ERROR_WRITE_FAILED TSRMLS_CC, "BulkWrite objects may only be executed once and this instance has already been executed"); return false; } if (!phongo_split_namespace(namespace, &bulk_write->database, &bulk_write->collection)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace); return false; } mongoc_bulk_operation_set_database(bulk, bulk_write->database); mongoc_bulk_operation_set_collection(bulk, bulk_write->collection); 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); } if (server_id > 0) { mongoc_bulk_operation_set_hint(bulk, server_id); } success = mongoc_bulk_operation_execute(bulk, &reply, &error); bulk_write->executed = true; /* Write succeeded and the user doesn't care for the results */ if (success && !return_value_used) { bson_destroy(&reply); return true; } /* Check for connection related exceptions */ if (EG(exception)) { bson_destroy(&reply); return false; } writeresult = phongo_writeresult_init(return_value, &reply, client, mongoc_bulk_operation_get_hint(bulk) TSRMLS_CC); writeresult->write_concern = mongoc_write_concern_copy(write_concern); /* The Write failed */ if (!success) { if ((error.domain == MONGOC_ERROR_COMMAND && error.code != MONGOC_ERROR_COMMAND_INVALID_ARG) || error.domain == MONGOC_ERROR_WRITE_CONCERN) { phongo_throw_exception(PHONGO_ERROR_WRITE_FAILED TSRMLS_CC, "%s", error.message); phongo_add_exception_prop(ZEND_STRL("writeResult"), return_value TSRMLS_CC); } else { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); } } bson_destroy(&reply); return success; } /* }}} */ /* Advance the cursor and return whether there is an error. On error, the cursor * will be destroyed and an exception will be thrown. */ static bool phongo_advance_cursor_and_check_for_error(mongoc_cursor_t *cursor TSRMLS_DC) { const bson_t *doc; 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; } } return true; } int phongo_execute_query(mongoc_client_t *client, const char *namespace, zval *zquery, zval *zreadPreference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */ { const php_phongo_query_t *query; 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); query = Z_QUERY_OBJ_P(zquery); if (query->read_concern) { mongoc_collection_set_read_concern(collection, query->read_concern); } cursor = mongoc_collection_find_with_opts(collection, query->filter, query->opts, phongo_read_preference_from_zval(zreadPreference TSRMLS_CC)); mongoc_collection_destroy(collection); if (server_id > 0 && !mongoc_cursor_set_hint(cursor, server_id)) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "%s", "Could not set cursor server_id"); return false; } /* maxAwaitTimeMS must be set before the cursor is sent */ if (query->max_await_time_ms) { mongoc_cursor_set_max_await_time_ms(cursor, query->max_await_time_ms); } if (!phongo_advance_cursor_and_check_for_error(cursor TSRMLS_CC)) { return false; } if (!return_value_used) { mongoc_cursor_destroy(cursor); return true; } phongo_cursor_init_for_query(return_value, client, cursor, namespace, zquery, zreadPreference TSRMLS_CC); return true; } /* }}} */ int phongo_execute_command(mongoc_client_t *client, const char *db, zval *zcommand, zval *zreadPreference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */ { const php_phongo_command_t *command; mongoc_cursor_t *cursor; bson_iter_t iter; command = Z_COMMAND_OBJ_P(zcommand); cursor = mongoc_client_command(client, db, MONGOC_QUERY_NONE, 0, 1, 0, command->bson, NULL, phongo_read_preference_from_zval(zreadPreference TSRMLS_CC)); if (server_id > 0 && !mongoc_cursor_set_hint(cursor, server_id)) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "%s", "Could not set cursor server_id"); return false; } if (!phongo_advance_cursor_and_check_for_error(cursor TSRMLS_CC)) { return false; } if (!return_value_used) { mongoc_cursor_destroy(cursor); return true; } if (bson_iter_init_find(&iter, mongoc_cursor_current(cursor), "cursor") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { mongoc_cursor_t *cmd_cursor; /* According to mongoc_cursor_new_from_command_reply(), the reply bson_t * is ultimately destroyed on both success and failure. Use bson_copy() * to create a writable copy of the const bson_t we fetched above. */ cmd_cursor = mongoc_cursor_new_from_command_reply(client, bson_copy(mongoc_cursor_current(cursor)), mongoc_cursor_get_hint(cursor)); mongoc_cursor_destroy(cursor); if (!phongo_advance_cursor_and_check_for_error(cmd_cursor TSRMLS_CC)) { return false; } phongo_cursor_init_for_command(return_value, client, cmd_cursor, db, zcommand, zreadPreference TSRMLS_CC); return true; } phongo_cursor_init_for_command(return_value, client, cursor, db, zcommand, zreadPreference TSRMLS_CC); return true; } /* }}} */ /* }}} */ /* {{{ 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; } /* }}} */ /* }}} */ /* {{{ 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); intern->initialized = true; } /* }}} */ php_phongo_server_description_type_t php_phongo_server_description_type(mongoc_server_description_t *sd) { const char* name = mongoc_server_description_type(sd); int i; for (i = 0; i < PHONGO_SERVER_DESCRIPTION_TYPES; i++) { if (!strcmp(name, php_phongo_server_description_type_map[i].name)) { return php_phongo_server_description_type_map[i].type; } } return PHONGO_SERVER_UNKNOWN; } void php_phongo_server_to_zval(zval *retval, mongoc_server_description_t *sd) /* {{{ */ { mongoc_host_list_t *host = mongoc_server_description_host(sd); const bson_t *is_master = mongoc_server_description_ismaster(sd); bson_iter_t iter; array_init(retval); ADD_ASSOC_STRING(retval, "host", host->host); ADD_ASSOC_LONG_EX(retval, "port", host->port); ADD_ASSOC_LONG_EX(retval, "type", php_phongo_server_description_type(sd)); ADD_ASSOC_BOOL_EX(retval, "is_primary", !strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_PRIMARY].name)); ADD_ASSOC_BOOL_EX(retval, "is_secondary", !strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_SECONDARY].name)); ADD_ASSOC_BOOL_EX(retval, "is_arbiter", !strcmp(mongoc_server_description_type(sd), php_phongo_server_description_type_map[PHONGO_SERVER_RS_ARBITER].name)); ADD_ASSOC_BOOL_EX(retval, "is_hidden", bson_iter_init_find_case(&iter, is_master, "hidden") && bson_iter_as_bool(&iter)); ADD_ASSOC_BOOL_EX(retval, "is_passive", bson_iter_init_find_case(&iter, is_master, "passive") && bson_iter_as_bool(&iter)); if (bson_iter_init_find(&iter, is_master, "tags") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { const uint8_t *bytes; uint32_t 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; bson_iter_document(&iter, &len, &bytes); php_phongo_bson_to_zval_ex(bytes, 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; php_phongo_bson_to_zval_ex(bson_get_data(is_master), 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", (phongo_long) mongoc_server_description_round_trip_time(sd)); } /* }}} */ 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", level); } } /* }}} */ /* Prepare tagSets for BSON encoding by converting each array in the set to an * object. This ensures that empty arrays will serialize as empty documents. * * php_phongo_read_preference_tags_are_valid() handles actual validation of the * tag set structure. */ void php_phongo_read_preference_prep_tagsets(zval *tagSets TSRMLS_DC) /* {{{ */ { HashTable *ht_data; if (Z_TYPE_P(tagSets) != IS_ARRAY) { return; } ht_data = HASH_OF(tagSets); #if PHP_VERSION_ID >= 70000 { zval *tagSet; ZEND_HASH_FOREACH_VAL(ht_data, tagSet) { ZVAL_DEREF(tagSet); if (Z_TYPE_P(tagSet) == IS_ARRAY) { SEPARATE_ZVAL_NOREF(tagSet); convert_to_object(tagSet); } } ZEND_HASH_FOREACH_END(); } #else { HashPosition pos; zval **tagSet; for (zend_hash_internal_pointer_reset_ex(ht_data, &pos); zend_hash_get_current_data_ex(ht_data, (void **) &tagSet, &pos) == SUCCESS; zend_hash_move_forward_ex(ht_data, &pos)) { if (Z_TYPE_PP(tagSet) == IS_ARRAY) { SEPARATE_ZVAL_IF_NOT_REF(tagSet); convert_to_object(*tagSet); } } } #endif return; } /* }}} */ /* Checks if tags is valid to set on a mongoc_read_prefs_t. It may be null or an * array of one or more documents. */ bool php_phongo_read_preference_tags_are_valid(const bson_t *tags) /* {{{ */ { bson_iter_t iter; if (bson_empty0(tags)) { return true; } if (!bson_iter_init(&iter, tags)) { return false; } while (bson_iter_next(&iter)) { if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { return false; } } return true; } /* }}} */ void php_phongo_read_preference_to_zval(zval *retval, const mongoc_read_prefs_t *read_prefs) /* {{{ */ { const bson_t *tags = mongoc_read_prefs_get_tags(read_prefs); mongoc_read_mode_t mode = mongoc_read_prefs_get_mode(read_prefs); array_init_size(retval, 3); switch (mode) { case MONGOC_READ_PRIMARY: ADD_ASSOC_STRING(retval, "mode", "primary"); break; case MONGOC_READ_PRIMARY_PREFERRED: ADD_ASSOC_STRING(retval, "mode", "primaryPreferred"); break; case MONGOC_READ_SECONDARY: ADD_ASSOC_STRING(retval, "mode", "secondary"); break; case MONGOC_READ_SECONDARY_PREFERRED: ADD_ASSOC_STRING(retval, "mode", "secondaryPreferred"); break; case MONGOC_READ_NEAREST: ADD_ASSOC_STRING(retval, "mode", "nearest"); break; default: /* Do nothing */ break; } if (!bson_empty0(tags)) { /* Use PHONGO_TYPEMAP_NATIVE_ARRAY for the root type since tags is an * array; however, inner documents and arrays can use the default. */ php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; php_phongo_bson_to_zval_ex(bson_get_data(tags), 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 } if (mongoc_read_prefs_get_max_staleness_seconds(read_prefs) != MONGOC_NO_MAX_STALENESS) { ADD_ASSOC_LONG_EX(retval, "maxStalenessSeconds", mongoc_read_prefs_get_max_staleness_seconds(read_prefs)); } } /* }}} */ 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); const int32_t wtimeout = mongoc_write_concern_get_wtimeout(write_concern); array_init_size(retval, 4); if (wtag) { ADD_ASSOC_STRING(retval, "w", wtag); } else if (mongoc_write_concern_get_wmajority(write_concern)) { ADD_ASSOC_STRING(retval, "w", PHONGO_WRITE_CONCERN_W_MAJORITY); } else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) { ADD_ASSOC_LONG_EX(retval, "w", w); } if (mongoc_write_concern_journal_is_set(write_concern)) { ADD_ASSOC_BOOL_EX(retval, "j", mongoc_write_concern_get_journal(write_concern)); } if (wtimeout != 0) { ADD_ASSOC_LONG_EX(retval, "wtimeout", wtimeout); } } /* }}} */ /* }}} */ static mongoc_uri_t *php_phongo_make_uri(const char *uri_string, bson_t *options TSRMLS_DC) /* {{{ */ { mongoc_uri_t *uri; bson_error_t error; uri = mongoc_uri_new_with_error(uri_string, &error); MONGOC_DEBUG("Connection string: '%s'", uri_string); if (!uri) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse MongoDB URI: '%s'. %s.", uri_string, error.message); return NULL; } return uri; } /* }}} */ static const char *php_phongo_bson_type_to_string(bson_type_t type) /* {{{ */ { switch (type) { case BSON_TYPE_EOD: return "EOD"; case BSON_TYPE_DOUBLE: return "double"; case BSON_TYPE_UTF8: return "string"; case BSON_TYPE_DOCUMENT: return "document"; case BSON_TYPE_ARRAY: return "array"; case BSON_TYPE_BINARY: return "Binary"; case BSON_TYPE_UNDEFINED: return "undefined"; case BSON_TYPE_OID: return "ObjectId"; case BSON_TYPE_BOOL: return "boolean"; case BSON_TYPE_DATE_TIME: return "UTCDateTime"; case BSON_TYPE_NULL: return "null"; case BSON_TYPE_REGEX: return "Regex"; case BSON_TYPE_DBPOINTER: return "DBPointer"; case BSON_TYPE_CODE: return "Javascript"; case BSON_TYPE_SYMBOL: return "symbol"; case BSON_TYPE_CODEWSCOPE: return "Javascript with scope"; case BSON_TYPE_INT32: return "32-bit integer"; case BSON_TYPE_TIMESTAMP: return "Timestamp"; case BSON_TYPE_INT64: return "64-bit integer"; case BSON_TYPE_DECIMAL128: return "Decimal128"; case BSON_TYPE_MAXKEY: return "MaxKey"; case BSON_TYPE_MINKEY: return "MinKey"; default: return "unknown"; } } /* }}} */ #define PHONGO_URI_INVALID_TYPE(iter, expected) \ phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, \ "Expected %s for \"%s\" URI option, %s given", \ (expected), \ bson_iter_key(&(iter)), \ php_phongo_bson_type_to_string(bson_iter_type(&(iter)))) static bool php_phongo_apply_options_to_uri(mongoc_uri_t *uri, bson_t *options TSRMLS_DC) /* {{{ */ { bson_iter_t iter; /* Return early if there are no options to apply */ if (bson_empty0(options) || !bson_iter_init(&iter, options)) { return true; } while (bson_iter_next(&iter)) { const char *key = bson_iter_key(&iter); /* Skip read preference, read concern, and write concern options, as * those will be processed by other functions. */ if (!strcasecmp(key, MONGOC_URI_JOURNAL) || !strcasecmp(key, MONGOC_URI_MAXSTALENESSSECONDS) || !strcasecmp(key, MONGOC_URI_READCONCERNLEVEL) || !strcasecmp(key, MONGOC_URI_READPREFERENCE) || !strcasecmp(key, MONGOC_URI_READPREFERENCETAGS) || !strcasecmp(key, MONGOC_URI_SAFE) || !strcasecmp(key, MONGOC_URI_SLAVEOK) || !strcasecmp(key, MONGOC_URI_W) || !strcasecmp(key, MONGOC_URI_WTIMEOUTMS)) { continue; } if (mongoc_uri_option_is_bool(key)) { /* The option's type is not validated because bson_iter_as_bool() is * used to cast the value to a boolean. Validation may be introduced * in PHPC-990. */ if (!mongoc_uri_set_option_as_bool(uri, key, bson_iter_as_bool(&iter))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); return false; } continue; } if (mongoc_uri_option_is_int32(key)) { if (!BSON_ITER_HOLDS_INT32(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "32-bit integer"); return false; } if (!mongoc_uri_set_option_as_int32(uri, key, bson_iter_int32(&iter))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); return false; } continue; } if (mongoc_uri_option_is_utf8(key)) { if (!BSON_ITER_HOLDS_UTF8(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "string"); return false; } if (!mongoc_uri_set_option_as_utf8(uri, key, bson_iter_utf8(&iter, NULL))) { /* Assignment uses mongoc_uri_set_appname() for the "appname" * option, which validates length in addition to UTF-8 encoding. * For BC, we report the invalid string to the user. */ if (!strcasecmp(key, MONGOC_URI_APPNAME)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid appname value: '%s'", bson_iter_utf8(&iter, NULL)); } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); } return false; } continue; } if (!strcasecmp(key, "username")) { if (!BSON_ITER_HOLDS_UTF8(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "string"); return false; } if (!mongoc_uri_set_username(uri, bson_iter_utf8(&iter, NULL))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); return false; } continue; } if (!strcasecmp(key, "password")) { if (!BSON_ITER_HOLDS_UTF8(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "string"); return false; } if (!mongoc_uri_set_password(uri, bson_iter_utf8(&iter, NULL))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); return false; } continue; } if (!strcasecmp(key, MONGOC_URI_AUTHMECHANISM)) { if (!BSON_ITER_HOLDS_UTF8(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "string"); return false; } if (!mongoc_uri_set_auth_mechanism(uri, bson_iter_utf8(&iter, NULL))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); return false; } continue; } if (!strcasecmp(key, MONGOC_URI_AUTHSOURCE)) { if (!BSON_ITER_HOLDS_UTF8(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "string"); return false; } if (!mongoc_uri_set_auth_source(uri, bson_iter_utf8(&iter, NULL))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); return false; } continue; } if (!strcasecmp(key, MONGOC_URI_AUTHMECHANISMPROPERTIES)) { bson_t properties; uint32_t len; const uint8_t *data; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "array or object"); return false; } bson_iter_document(&iter, &len, &data); if (!bson_init_static(&properties, data, len)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Could not initialize BSON structure for auth mechanism properties"); return false; } if (!mongoc_uri_set_mechanism_properties(uri, &properties)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" URI option", key); return false; } continue; } } return true; } /* }}} */ static bool php_phongo_apply_rc_options_to_uri(mongoc_uri_t *uri, 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_uri_get_read_concern(uri))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t 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, MONGOC_URI_READCONCERNLEVEL)) { return true; } new_rc = mongoc_read_concern_copy(old_rc); if (bson_iter_init_find_case(&iter, options, MONGOC_URI_READCONCERNLEVEL)) { if (!BSON_ITER_HOLDS_UTF8(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "string"); mongoc_read_concern_destroy(new_rc); return false; } mongoc_read_concern_set_level(new_rc, bson_iter_utf8(&iter, NULL)); } mongoc_uri_set_read_concern(uri, new_rc); mongoc_read_concern_destroy(new_rc); return true; } /* }}} */ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t *uri, 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_uri_get_read_prefs_t(uri))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t 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, MONGOC_URI_SLAVEOK) && !bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCE) && !bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCETAGS) && !bson_iter_init_find_case(&iter, options, MONGOC_URI_MAXSTALENESSSECONDS) ) { return true; } new_rp = mongoc_read_prefs_copy(old_rp); if (bson_iter_init_find_case(&iter, options, MONGOC_URI_SLAVEOK)) { if (!BSON_ITER_HOLDS_BOOL(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "boolean"); mongoc_read_prefs_destroy(new_rp); return false; } if (bson_iter_bool(&iter)) { mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED); } } if (bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCE)) { const char *str; if (!BSON_ITER_HOLDS_UTF8(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "string"); mongoc_read_prefs_destroy(new_rp); return false; } 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 %s value: '%s'", bson_iter_key(&iter), str); mongoc_read_prefs_destroy(new_rp); return false; } } if (bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCETAGS)) { bson_t tags; uint32_t len; const uint8_t *data; if (!BSON_ITER_HOLDS_ARRAY(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "array"); mongoc_read_prefs_destroy(new_rp); return false; } bson_iter_array(&iter, &len, &data); if (!bson_init_static(&tags, data, len)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Could not initialize BSON structure for read preference tags"); mongoc_read_prefs_destroy(new_rp); return false; } if (!php_phongo_read_preference_tags_are_valid(&tags)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference tags must be an array of zero or more documents"); mongoc_read_prefs_destroy(new_rp); return false; } 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; } /* Handle maxStalenessSeconds, and make sure it is not combined with primary * readPreference */ if (bson_iter_init_find_case(&iter, options, MONGOC_URI_MAXSTALENESSSECONDS)) { int64_t max_staleness_seconds; if (!BSON_ITER_HOLDS_INT(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "integer"); mongoc_read_prefs_destroy(new_rp); return false; } max_staleness_seconds = bson_iter_as_int64(&iter); if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be >= %d, %" PRId64 " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, max_staleness_seconds); mongoc_read_prefs_destroy(new_rp); return false; } if (max_staleness_seconds > INT32_MAX) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be <= %d, %" PRId64 " given", INT32_MAX, max_staleness_seconds); mongoc_read_prefs_destroy(new_rp); return false; } if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with maxStalenessSeconds"); mongoc_read_prefs_destroy(new_rp); return false; } } mongoc_read_prefs_set_max_staleness_seconds(new_rp, max_staleness_seconds); } /* 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_uri_set_read_prefs_t(uri, new_rp); mongoc_read_prefs_destroy(new_rp); return true; } /* }}} */ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t *uri, 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_uri_get_write_concern(uri))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t 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, MONGOC_URI_JOURNAL) && !bson_iter_init_find_case(&iter, options, MONGOC_URI_SAFE) && !bson_iter_init_find_case(&iter, options, MONGOC_URI_W) && !bson_iter_init_find_case(&iter, options, MONGOC_URI_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, MONGOC_URI_SAFE)) { if (!BSON_ITER_HOLDS_BOOL(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "boolean"); mongoc_write_concern_destroy(new_wc); return false; } 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, MONGOC_URI_WTIMEOUTMS)) { if (!BSON_ITER_HOLDS_INT32(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "32-bit integer"); mongoc_write_concern_destroy(new_wc); return false; } wtimeoutms = bson_iter_int32(&iter); } if (bson_iter_init_find_case(&iter, options, MONGOC_URI_JOURNAL)) { if (!BSON_ITER_HOLDS_BOOL(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "boolean"); mongoc_write_concern_destroy(new_wc); return false; } mongoc_write_concern_set_journal(new_wc, bson_iter_bool(&iter)); } if (bson_iter_init_find_case(&iter, options, MONGOC_URI_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); } } else { PHONGO_URI_INVALID_TYPE(iter, "32-bit integer or string"); mongoc_write_concern_destroy(new_wc); return false; } } /* 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_uri_set_write_concern(uri, new_wc); mongoc_write_concern_destroy(new_wc); return true; } /* }}} */ #ifdef MONGOC_ENABLE_SSL static inline char *php_phongo_fetch_ssl_opt_string(zval *zoptions, const char *key, int key_len) { int plen; zend_bool pfree; char *pval, *value; pval = php_array_fetchl_string(zoptions, key, key_len, &plen, &pfree); value = pfree ? pval : estrndup(pval, plen); return value; } static mongoc_ssl_opt_t *php_phongo_make_ssl_opt(zval *zoptions TSRMLS_DC) { mongoc_ssl_opt_t *ssl_opt; if (!zoptions) { return NULL; } #if defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) if (php_array_existsc(zoptions, "ca_dir")) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"ca_dir\" option is not supported by Secure Channel and Secure Transport"); return NULL; } if (php_array_existsc(zoptions, "capath")) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"capath\" option is not supported by Secure Channel and Secure Transport"); return NULL; } #endif #if defined(MONGOC_ENABLE_SSL_LIBRESSL) || defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) if (php_array_existsc(zoptions, "crl_file")) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "\"crl_file\" option is not supported by LibreSSL and Secure Transport"); return NULL; } #endif ssl_opt = ecalloc(1, sizeof(mongoc_ssl_opt_t)); /* Check canonical option names first and fall back to SSL context options * for backwards compatibility. */ if (php_array_existsc(zoptions, "allow_invalid_hostname")) { ssl_opt->allow_invalid_hostname = php_array_fetchc_bool(zoptions, "allow_invalid_hostname"); } if (php_array_existsc(zoptions, "weak_cert_validation")) { ssl_opt->weak_cert_validation = php_array_fetchc_bool(zoptions, "weak_cert_validation"); } else if (php_array_existsc(zoptions, "allow_self_signed")) { ssl_opt->weak_cert_validation = php_array_fetchc_bool(zoptions, "allow_self_signed"); } if (php_array_existsc(zoptions, "pem_file")) { ssl_opt->pem_file = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("pem_file")); } else if (php_array_existsc(zoptions, "local_cert")) { ssl_opt->pem_file = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("local_cert")); } if (php_array_existsc(zoptions, "pem_pwd")) { ssl_opt->pem_pwd = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("pem_pwd")); } else if (php_array_existsc(zoptions, "passphrase")) { ssl_opt->pem_pwd = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("passphrase")); } if (php_array_existsc(zoptions, "ca_file")) { ssl_opt->ca_file = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("ca_file")); } else if (php_array_existsc(zoptions, "cafile")) { ssl_opt->ca_file = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("cafile")); } if (php_array_existsc(zoptions, "ca_dir")) { ssl_opt->ca_dir = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("ca_dir")); } else if (php_array_existsc(zoptions, "capath")) { ssl_opt->ca_dir = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("capath")); } if (php_array_existsc(zoptions, "crl_file")) { ssl_opt->crl_file = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL("crl_file")); } return ssl_opt; } static void php_phongo_free_ssl_opt(mongoc_ssl_opt_t *ssl_opt) { if (ssl_opt->pem_file) { str_efree(ssl_opt->pem_file); } if (ssl_opt->pem_pwd) { str_efree(ssl_opt->pem_pwd); } if (ssl_opt->ca_file) { str_efree(ssl_opt->ca_file); } if (ssl_opt->ca_dir) { str_efree(ssl_opt->ca_dir); } if (ssl_opt->crl_file) { str_efree(ssl_opt->crl_file); } efree(ssl_opt); } #endif /* APM callbacks */ static void php_phongo_dispatch_handlers(const char *name, zval *z_event) { #if PHP_VERSION_ID >= 70000 zval *value; ZEND_HASH_FOREACH_VAL(MONGODB_G(subscribers), value) { /* We can't use the zend_call_method_with_1_params macro here, as it * does a sizeof() on the name argument, which does only work with * constant names, but not with parameterized ones as it does * "sizeof(char*)" in that case. */ zend_call_method(value, NULL, NULL, name, strlen(name), NULL, 1, z_event, NULL TSRMLS_CC); } ZEND_HASH_FOREACH_END(); #else HashPosition pos; TSRMLS_FETCH(); zend_hash_internal_pointer_reset_ex(MONGODB_G(subscribers), &pos); for (;; zend_hash_move_forward_ex(MONGODB_G(subscribers), &pos)) { zval **value; if (zend_hash_get_current_data_ex(MONGODB_G(subscribers), (void **) &value, &pos) == FAILURE) { break; } /* We can't use the zend_call_method_with_1_params macro here, as it * does a sizeof() on the name argument, which does only work with * constant names, but not with parameterized ones as it does * "sizeof(char*)" in that case. */ zend_call_method(value, NULL, NULL, name, strlen(name), NULL, 1, z_event, NULL TSRMLS_CC); } #endif } static void php_phongo_command_started(const mongoc_apm_command_started_t *event) { php_phongo_commandstartedevent_t *p_event; #if PHP_VERSION_ID >= 70000 zval z_event; #else zval *z_event = NULL; #endif TSRMLS_FETCH(); /* Return early if there are no APM subscribers to notify */ if (!MONGODB_G(subscribers) || zend_hash_num_elements(MONGODB_G(subscribers)) == 0) { return; } #if PHP_VERSION_ID >= 70000 object_init_ex(&z_event, php_phongo_commandstartedevent_ce); p_event = Z_COMMANDSTARTEDEVENT_OBJ_P(&z_event); #else MAKE_STD_ZVAL(z_event); object_init_ex(z_event, php_phongo_commandstartedevent_ce); p_event = Z_COMMANDSTARTEDEVENT_OBJ_P(z_event); #endif p_event->client = mongoc_apm_command_started_get_context(event); p_event->command_name = estrdup(mongoc_apm_command_started_get_command_name(event)); p_event->server_id = mongoc_apm_command_started_get_server_id(event); p_event->operation_id = mongoc_apm_command_started_get_operation_id(event); p_event->request_id = mongoc_apm_command_started_get_request_id(event); p_event->command = bson_copy(mongoc_apm_command_started_get_command(event)); p_event->database_name = estrdup(mongoc_apm_command_started_get_database_name(event)); #if PHP_VERSION_ID >= 70000 php_phongo_dispatch_handlers("commandStarted", &z_event); #else php_phongo_dispatch_handlers("commandStarted", z_event); #endif zval_ptr_dtor(&z_event); } static void php_phongo_command_succeeded(const mongoc_apm_command_succeeded_t *event) { php_phongo_commandsucceededevent_t *p_event; #if PHP_VERSION_ID >= 70000 zval z_event; #else zval *z_event = NULL; #endif TSRMLS_FETCH(); /* Return early if there are no APM subscribers to notify */ if (!MONGODB_G(subscribers) || zend_hash_num_elements(MONGODB_G(subscribers)) == 0) { return; } #if PHP_VERSION_ID >= 70000 object_init_ex(&z_event, php_phongo_commandsucceededevent_ce); p_event = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(&z_event); #else MAKE_STD_ZVAL(z_event); object_init_ex(z_event, php_phongo_commandsucceededevent_ce); p_event = Z_COMMANDSUCCEEDEDEVENT_OBJ_P(z_event); #endif p_event->client = mongoc_apm_command_succeeded_get_context(event); p_event->command_name = estrdup(mongoc_apm_command_succeeded_get_command_name(event)); p_event->server_id = mongoc_apm_command_succeeded_get_server_id(event); p_event->operation_id = mongoc_apm_command_succeeded_get_operation_id(event); p_event->request_id = mongoc_apm_command_succeeded_get_request_id(event); p_event->duration_micros = mongoc_apm_command_succeeded_get_duration(event); p_event->reply = bson_copy(mongoc_apm_command_succeeded_get_reply(event)); #if PHP_VERSION_ID >= 70000 php_phongo_dispatch_handlers("commandSucceeded", &z_event); #else php_phongo_dispatch_handlers("commandSucceeded", z_event); #endif zval_ptr_dtor(&z_event); } static void php_phongo_command_failed(const mongoc_apm_command_failed_t *event) { php_phongo_commandfailedevent_t *p_event; #if PHP_VERSION_ID >= 70000 zval z_event; #else zval *z_event = NULL; #endif bson_error_t tmp_error; zend_class_entry *default_exception_ce; TSRMLS_FETCH(); default_exception_ce = zend_exception_get_default(TSRMLS_C); /* Return early if there are no APM subscribers to notify */ if (!MONGODB_G(subscribers) || zend_hash_num_elements(MONGODB_G(subscribers)) == 0) { return; } #if PHP_VERSION_ID >= 70000 object_init_ex(&z_event, php_phongo_commandfailedevent_ce); p_event = Z_COMMANDFAILEDEVENT_OBJ_P(&z_event); #else MAKE_STD_ZVAL(z_event); object_init_ex(z_event, php_phongo_commandfailedevent_ce); p_event = Z_COMMANDFAILEDEVENT_OBJ_P(z_event); #endif p_event->client = mongoc_apm_command_failed_get_context(event); p_event->command_name = estrdup(mongoc_apm_command_failed_get_command_name(event)); p_event->server_id = mongoc_apm_command_failed_get_server_id(event); p_event->operation_id = mongoc_apm_command_failed_get_operation_id(event); p_event->request_id = mongoc_apm_command_failed_get_request_id(event); p_event->duration_micros = mongoc_apm_command_failed_get_duration(event); /* We need to process and convert the error right here, otherwise * debug_info will turn into a recursive loop, and with the wrong trace * locations */ mongoc_apm_command_failed_get_error(event, &tmp_error); { #if PHP_VERSION_ID < 70000 MAKE_STD_ZVAL(p_event->z_error); object_init_ex(p_event->z_error, phongo_exception_from_mongoc_domain(tmp_error.domain, tmp_error.code)); zend_update_property_string(default_exception_ce, p_event->z_error, ZEND_STRL("message"), tmp_error.message TSRMLS_CC); zend_update_property_long(default_exception_ce, p_event->z_error, ZEND_STRL("code"), tmp_error.code TSRMLS_CC); #else object_init_ex(&p_event->z_error, phongo_exception_from_mongoc_domain(tmp_error.domain, tmp_error.code)); zend_update_property_string(default_exception_ce, &p_event->z_error, ZEND_STRL("message"), tmp_error.message TSRMLS_CC); zend_update_property_long(default_exception_ce, &p_event->z_error, ZEND_STRL("code"), tmp_error.code TSRMLS_CC); #endif } #if PHP_VERSION_ID >= 70000 php_phongo_dispatch_handlers("commandFailed", &z_event); #else php_phongo_dispatch_handlers("commandFailed", z_event); #endif zval_ptr_dtor(&z_event); } /* Sets the callbacks for APM */ int php_phongo_set_monitoring_callbacks(mongoc_client_t *client) { int retval; mongoc_apm_callbacks_t *callbacks = mongoc_apm_callbacks_new(); mongoc_apm_set_command_started_cb(callbacks, php_phongo_command_started); mongoc_apm_set_command_succeeded_cb(callbacks, php_phongo_command_succeeded); mongoc_apm_set_command_failed_cb(callbacks, php_phongo_command_failed); retval = mongoc_client_set_apm_callbacks(client, callbacks, client); mongoc_apm_callbacks_destroy(callbacks); return retval; } /* Creates a hash for a client by concatenating the URI string with serialized * options arrays. On success, a persistent string is returned (i.e. pefree() * should be used to free it) and hash_len will be set to the string's length. * On error, an exception will have been thrown and NULL will be returned. */ static char *php_phongo_manager_make_client_hash(const char *uri_string, zval *options, zval *driverOptions, size_t *hash_len TSRMLS_DC) { char *hash = NULL; smart_str var_buf = {0}; php_serialize_data_t var_hash; #if PHP_VERSION_ID >= 70000 zval args; array_init_size(&args, 4); ADD_ASSOC_LONG_EX(&args, "pid", getpid()); ADD_ASSOC_STRING(&args, "uri", uri_string); if (options) { ADD_ASSOC_ZVAL_EX(&args, "options", options); Z_ADDREF_P(options); } else { ADD_ASSOC_NULL_EX(&args, "options"); } if (driverOptions) { ADD_ASSOC_ZVAL_EX(&args, "driverOptions", driverOptions); Z_ADDREF_P(driverOptions); } else { ADD_ASSOC_NULL_EX(&args, "driverOptions"); } PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&var_buf, &args, &var_hash); PHP_VAR_SERIALIZE_DESTROY(var_hash); if (!EG(exception)) { *hash_len = ZSTR_LEN(var_buf.s); hash = pestrndup(ZSTR_VAL(var_buf.s), *hash_len, 1); } zval_ptr_dtor(&args); #else zval *args; MAKE_STD_ZVAL(args); array_init_size(args, 4); ADD_ASSOC_LONG_EX(args, "pid", getpid()); ADD_ASSOC_STRING(args, "uri", uri_string); if (options) { ADD_ASSOC_ZVAL_EX(args, "options", options); Z_ADDREF_P(options); } else { ADD_ASSOC_NULL_EX(args, "options"); } if (driverOptions) { ADD_ASSOC_ZVAL_EX(args, "driverOptions", driverOptions); Z_ADDREF_P(driverOptions); } else { ADD_ASSOC_NULL_EX(args, "driverOptions"); } PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&var_buf, &args, &var_hash TSRMLS_CC); PHP_VAR_SERIALIZE_DESTROY(var_hash); if (!EG(exception)) { *hash_len = var_buf.len; hash = pestrndup(var_buf.c, *hash_len, 1); } zval_ptr_dtor(&args); #endif smart_str_free(&var_buf); return hash; } static mongoc_client_t *php_phongo_make_mongo_client(const mongoc_uri_t *uri TSRMLS_DC) /* {{{ */ { const char *mongoc_version, *bson_version; #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", PHP_MONGODB_VERSION, PHP_MONGODB_STABILITY, MONGOC_VERSION_S, mongoc_version, BSON_VERSION_S, bson_version, PHP_VERSION ); return mongoc_client_new_from_uri(uri); } /* }}} */ static void php_phongo_persist_client(const char *hash, size_t hash_len, mongoc_client_t *client TSRMLS_DC) { php_phongo_pclient_t *pclient = (php_phongo_pclient_t *) pecalloc(1, sizeof(php_phongo_pclient_t), 1); pclient->pid = (int) getpid(); pclient->client = client; #if PHP_VERSION_ID >= 70000 zend_hash_str_update_ptr(&MONGODB_G(pclients), hash, hash_len, pclient); #else zend_hash_update(&MONGODB_G(pclients), hash, hash_len + 1, &pclient, sizeof(php_phongo_pclient_t *), NULL); #endif } static mongoc_client_t *php_phongo_find_client(const char *hash, size_t hash_len TSRMLS_DC) { #if PHP_VERSION_ID >= 70000 php_phongo_pclient_t *pclient; if ((pclient = zend_hash_str_find_ptr(&MONGODB_G(pclients), hash, hash_len)) != NULL) { return pclient->client; } #else php_phongo_pclient_t **pclient; if (zend_hash_find(&MONGODB_G(pclients), hash, hash_len + 1, (void**) &pclient) == SUCCESS) { return (*pclient)->client; } #endif return NULL; } void phongo_manager_init(php_phongo_manager_t *manager, const char *uri_string, zval *options, zval *driverOptions TSRMLS_DC) /* {{{ */ { char *hash = NULL; size_t hash_len = 0; bson_t bson_options = BSON_INITIALIZER; mongoc_uri_t *uri = NULL; #ifdef MONGOC_ENABLE_SSL mongoc_ssl_opt_t *ssl_opt = NULL; #endif if (!(hash = php_phongo_manager_make_client_hash(uri_string, options, driverOptions, &hash_len TSRMLS_CC))) { /* Exception should already have been thrown and there is nothing to free */ return; } if ((manager->client = php_phongo_find_client(hash, hash_len TSRMLS_CC))) { MONGOC_DEBUG("Found client for hash: %s\n", hash); goto cleanup; } if (options) { php_phongo_zval_to_bson(options, PHONGO_BSON_NONE, &bson_options, NULL TSRMLS_CC); } /* An exception may be thrown during BSON conversion */ if (EG(exception)) { goto cleanup; } if (!(uri = php_phongo_make_uri(uri_string, &bson_options TSRMLS_CC))) { /* Exception should already have been thrown */ goto cleanup; } if (!php_phongo_apply_options_to_uri(uri, &bson_options TSRMLS_CC) || !php_phongo_apply_rc_options_to_uri(uri, &bson_options TSRMLS_CC) || !php_phongo_apply_rp_options_to_uri(uri, &bson_options TSRMLS_CC) || !php_phongo_apply_wc_options_to_uri(uri, &bson_options TSRMLS_CC)) { /* Exception should already have been thrown */ goto cleanup; } #ifdef MONGOC_ENABLE_SSL /* Construct SSL options even if SSL is not enabled so that exceptions can * be thrown for unsupported driver options. */ ssl_opt = php_phongo_make_ssl_opt(driverOptions TSRMLS_CC); /* An exception may be thrown during SSL option creation */ if (EG(exception)) { goto cleanup; } #else if (mongoc_uri_get_ssl(uri)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot create SSL client. SSL is not enabled in this build."); goto cleanup; } #endif manager->client = php_phongo_make_mongo_client(uri TSRMLS_CC); if (!manager->client) { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to create Manager from URI: '%s'", uri_string); goto cleanup; } #ifdef MONGOC_ENABLE_SSL if (ssl_opt && mongoc_uri_get_ssl(uri)) { mongoc_client_set_ssl_opts(manager->client, ssl_opt); } #endif MONGOC_DEBUG("Created client hash: %s\n", hash); php_phongo_persist_client(hash, hash_len, manager->client TSRMLS_CC); cleanup: if (hash) { pefree(hash, 1); } bson_destroy(&bson_options); if (uri) { mongoc_uri_destroy(uri); } #ifdef MONGOC_ENABLE_SSL if (ssl_opt) { php_phongo_free_ssl_opt(ssl_opt); } #endif } /* }}} */ 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; intern->initialized = true; } /* }}} */ 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; intern->initialized = true; } /* }}} */ 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->code = estrndup(code, code_len); intern->code_len = code_len; intern->scope = 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_decimal128(zval *object, const bson_decimal128_t *decimal TSRMLS_DC) /* {{{ */ { php_phongo_decimal128_t *intern; object_init_ex(object, php_phongo_decimal128_ce); intern = Z_DECIMAL128_OBJ_P(object); memcpy(&intern->decimal, decimal, sizeof(bson_decimal128_t)); intern->initialized = true; } /* }}} */ /* qsort() compare callback for alphabetizing regex flags upon initialization */ static int php_phongo_regex_compare_flags(const void *f1, const void *f2) { if (* (const char *) f1 == * (const char *) f2) { return 0; } return (* (const char *) f1 > * (const char *) f2) ? 1 : -1; } 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); /* Ensure flags are alphabetized upon initialization. This may be removed * once CDRIVER-1883 is implemented. */ qsort((void *) intern->flags, intern->flags_len, 1, php_phongo_regex_compare_flags); } /* }}} */ /* {{{ Memory allocation wrappers */ static void* php_phongo_malloc(size_t num_bytes) /* {{{ */ { return pemalloc(num_bytes, 1); } /* }}} */ static void* php_phongo_calloc(size_t num_members, size_t num_bytes) /* {{{ */ { return pecalloc(num_members, num_bytes, 1); } /* }}} */ static void* php_phongo_realloc(void *mem, size_t num_bytes) { /* {{{ */ return perealloc(mem, num_bytes, 1); } /* }}} */ static void php_phongo_free(void *mem) /* {{{ */ { if (mem) { pefree(mem, 1); } } /* }}} */ /* }}} */ /* {{{ 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 && !ZSTR_VAL(new_value)[0]) || strcasecmp("0", ZSTR_VAL(new_value)) == 0 || strcasecmp("off", ZSTR_VAL(new_value)) == 0 || strcasecmp("no", ZSTR_VAL(new_value)) == 0 || strcasecmp("false", ZSTR_VAL(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(ZSTR_VAL(new_value), "stderr") == 0) { MONGODB_G(debug_fd) = stderr; } else if (strcasecmp(ZSTR_VAL(new_value), "stdout") == 0) { MONGODB_G(debug_fd) = stdout; } else if ( strcasecmp("1", ZSTR_VAL(new_value)) == 0 || strcasecmp("on", ZSTR_VAL(new_value)) == 0 || strcasecmp("yes", ZSTR_VAL(new_value)) == 0 || strcasecmp("true", ZSTR_VAL(new_value)) == 0 ) { tmp_dir = NULL; } else { tmp_dir = ZSTR_VAL(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 = ZSTR_VAL(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() /* }}} */ static inline void php_phongo_pclient_destroy(php_phongo_pclient_t *pclient) { /* Do not destroy mongoc_client_t objects created by other processes. This * ensures that we do not shutdown sockets that may still be in use by our * parent process (see: CDRIVER-2049). While this is a leak, we are already * in MSHUTDOWN at this point. */ if (pclient->pid == getpid()) { mongoc_client_destroy(pclient->client); } pefree(pclient, 1); } #if PHP_VERSION_ID >= 70000 static void php_phongo_pclient_dtor(zval *zv) { php_phongo_pclient_destroy((php_phongo_pclient_t *) Z_PTR_P(zv)); } #else static void php_phongo_pclient_dtor(void *pp) { php_phongo_pclient_destroy(*((php_phongo_pclient_t **) pp)); } #endif /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(mongodb) { /* Initialize HashTable for APM subscribers, which is initialized to NULL in * GINIT and destroyed and reset to NULL in RSHUTDOWN. */ if (MONGODB_G(subscribers) == NULL) { ALLOC_HASHTABLE(MONGODB_G(subscribers)); zend_hash_init(MONGODB_G(subscribers), 0, NULL, ZVAL_PTR_DTOR, 0); } return SUCCESS; } /* }}} */ /* {{{ 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 memset(mongodb_globals, 0, sizeof(zend_mongodb_globals)); mongodb_globals->bsonMemVTable = bsonMemVTable; /* Initialize HashTable for persistent clients */ zend_hash_init_ex(&mongodb_globals->pclients, 0, NULL, php_phongo_pclient_dtor, 1, 0); } /* }}} */ static zend_class_entry *php_phongo_fetch_internal_class(const char *class_name, size_t class_name_len TSRMLS_DC) { #if PHP_VERSION_ID >= 70000 zend_class_entry *pce; if ((pce = zend_hash_str_find_ptr(CG(class_table), class_name, class_name_len))) { return pce; } #else zend_class_entry **pce; if (zend_hash_find(CG(class_table), class_name, class_name_len + 1, (void **) &pce) == SUCCESS) { return *pce; } #endif return NULL; } /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(mongodb) { char *php_version_string; (void)type; /* We don't care if we are loaded via dl() or extension= */ REGISTER_INI_ENTRIES(); /* Initialize libmongoc */ mongoc_init(); /* Set handshake options */ php_version_string = malloc(4 + sizeof(PHP_VERSION) + 1); snprintf(php_version_string, 4 + sizeof(PHP_VERSION) + 1, "PHP %s", PHP_VERSION); mongoc_handshake_data_append("ext-mongodb:PHP", PHP_MONGODB_VERSION, php_version_string); free(php_version_string); /* 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; */ /* Initialize zend_class_entry dependencies. * * Although DateTimeImmutable was introduced in PHP 5.5.0, * php_date_get_immutable_ce() is not available in PHP versions before * 5.5.24 and 5.6.8. * * Although JsonSerializable was introduced in PHP 5.4.0, * php_json_serializable_ce is not exported in PHP versions before 5.4.26 * and 5.5.10. For later PHP versions, looking up the class manually also * helps with distros that disable LTDL_LAZY for dlopen() (e.g. Fedora). */ php_phongo_date_immutable_ce = php_phongo_fetch_internal_class(ZEND_STRL("datetimeimmutable") TSRMLS_CC); php_phongo_json_serializable_ce = php_phongo_fetch_internal_class(ZEND_STRL("jsonserializable") TSRMLS_CC); if (php_phongo_json_serializable_ce == NULL) { zend_error(E_ERROR, "JsonSerializable class is not defined. Please ensure that the 'json' module is loaded before the 'mongodb' module."); return FAILURE; } /* Register base BSON classes first */ php_phongo_type_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_serializable_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_unserializable_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_binary_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_decimal128_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_javascript_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_maxkey_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_minkey_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_objectid_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_regex_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_timestamp_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_utcdatetime_interface_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_binary_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_decimal128_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_javascript_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_maxkey_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_minkey_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_objectid_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_persistable_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_regex_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_timestamp_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_utcdatetime_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_command_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_cursor_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_cursorid_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_manager_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_query_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_readconcern_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_readpreference_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_server_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_writeerror_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_writeresult_init_ce(INIT_FUNC_ARGS_PASSTHRU); /* Register base exception classes first */ php_phongo_exception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_runtimeexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_connectionexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_writeexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_authenticationexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_bulkwriteexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_connectiontimeoutexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_executiontimeoutexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_invalidargumentexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_logicexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_sslconnectionexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_unexpectedvalueexception_init_ce(INIT_FUNC_ARGS_PASSTHRU); /* Register base APM classes first */ php_phongo_subscriber_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_commandsubscriber_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_commandstartedevent_init_ce(INIT_FUNC_ARGS_PASSTHRU); php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS_PASSTHRU); REGISTER_STRING_CONSTANT("MONGODB_VERSION", (char *)PHP_MONGODB_VERSION, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("MONGODB_STABILITY", (char *)PHP_MONGODB_STABILITY, 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= */ /* Destroy HashTable for persistent clients. The HashTable destructor will * destroy any mongoc_client_t objects that were created by this process. */ zend_hash_destroy(&MONGODB_G(pclients)); bson_mem_restore_vtable(); /* Cleanup after libmongoc */ mongoc_cleanup(); UNREGISTER_INI_ENTRIES(); return SUCCESS; } /* }}} */ /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(mongodb) { /* Destroy HashTable for APM subscribers, which was initialized in RINIT */ if (MONGODB_G(subscribers)) { zend_hash_destroy(MONGODB_G(subscribers)); FREE_HASHTABLE(MONGODB_G(subscribers)); MONGODB_G(subscribers) = NULL; } 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 extension version", PHP_MONGODB_VERSION); php_info_print_table_row(2, "MongoDB extension stability", PHP_MONGODB_STABILITY); #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 bundled version", BSON_VERSION_S); #endif #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 bundled version", MONGOC_VERSION_S); #endif #ifdef MONGOC_ENABLE_SSL php_info_print_table_row(2, "libmongoc SSL", "enabled"); # if defined(MONGOC_ENABLE_SSL_OPENSSL) php_info_print_table_row(2, "libmongoc SSL library", "OpenSSL"); # elif defined(MONGOC_ENABLE_SSL_LIBRESSL) php_info_print_table_row(2, "libmongoc SSL library", "LibreSSL"); # elif defined(MONGOC_ENABLE_SSL_SECURE_TRANSPORT) php_info_print_table_row(2, "libmongoc SSL library", "Secure Transport"); # elif defined(MONGOC_ENABLE_SSL_SECURE_CHANNEL) php_info_print_table_row(2, "libmongoc SSL library", "Secure Channel"); # else php_info_print_table_row(2, "libmongoc SSL library", "unknown"); # endif #else php_info_print_table_row(2, "libmongoc SSL", "disabled"); #endif #ifdef MONGOC_ENABLE_CRYPTO php_info_print_table_row(2, "libmongoc crypto", "enabled"); # if defined(MONGOC_ENABLE_CRYPTO_LIBCRYPTO) php_info_print_table_row(2, "libmongoc crypto library", "libcrypto"); # elif defined(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO) php_info_print_table_row(2, "libmongoc crypto library", "Common Crypto"); # elif defined(MONGOC_ENABLE_CRYPTO_CNG) php_info_print_table_row(2, "libmongoc crypto library", "CNG"); # else php_info_print_table_row(2, "libmongoc crypto library", "unknown"); # endif # ifdef MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE php_info_print_table_row(2, "libmongoc crypto system profile", "enabled"); # else php_info_print_table_row(2, "libmongoc crypto system profile", "disabled"); # endif #else php_info_print_table_row(2, "libmongoc crypto", "disabled"); #endif #ifdef MONGOC_ENABLE_SASL php_info_print_table_row(2, "libmongoc SASL", "enabled"); #else php_info_print_table_row(2, "libmongoc SASL", "disabled"); #endif php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } /* }}} */ /* }}} */ /* {{{ Shared function entries for disabling constructors and unserialize() */ PHP_FUNCTION(MongoDB_disabled___construct) /* {{{ */ { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Accessing private constructor"); } /* }}} */ PHP_FUNCTION(MongoDB_disabled___wakeup) /* {{{ */ { if (zend_parse_parameters_none() == FAILURE) { return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "%s", "MongoDB\\Driver objects cannot be serialized"); } /* }}} */ /* }}} */ /* {{{ 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_ARG_ARRAY_INFO(0, typemap, 0) 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(); ZEND_BEGIN_ARG_INFO_EX(ai_mongodb_driver_monitoring_subscriber, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, subscriber, MongoDB\\Driver\\Monitoring\\Subscriber, 0) ZEND_END_ARG_INFO(); static const zend_function_entry mongodb_functions[] = { ZEND_NS_NAMED_FE("MongoDB\\BSON", fromPHP, PHP_FN(MongoDB_BSON_fromPHP), ai_bson_fromPHP) ZEND_NS_NAMED_FE("MongoDB\\BSON", toPHP, PHP_FN(MongoDB_BSON_toPHP), ai_bson_toPHP) ZEND_NS_NAMED_FE("MongoDB\\BSON", toJSON, PHP_FN(MongoDB_BSON_toJSON), ai_bson_toJSON) ZEND_NS_NAMED_FE("MongoDB\\BSON", toCanonicalExtendedJSON, PHP_FN(MongoDB_BSON_toCanonicalExtendedJSON), ai_bson_toJSON) ZEND_NS_NAMED_FE("MongoDB\\BSON", toRelaxedExtendedJSON, PHP_FN(MongoDB_BSON_toRelaxedExtendedJSON), ai_bson_toJSON) ZEND_NS_NAMED_FE("MongoDB\\BSON", fromJSON, PHP_FN(MongoDB_BSON_fromJSON), ai_bson_fromJSON) ZEND_NS_NAMED_FE("MongoDB\\Driver\\Monitoring", addSubscriber, PHP_FN(MongoDB_Driver_Monitoring_addSubscriber), ai_mongodb_driver_monitoring_subscriber) ZEND_NS_NAMED_FE("MongoDB\\Driver\\Monitoring", removeSubscriber, PHP_FN(MongoDB_Driver_Monitoring_removeSubscriber), ai_mongodb_driver_monitoring_subscriber) PHP_FE_END }; /* }}} */ static const zend_module_dep mongodb_deps[] = { ZEND_MOD_REQUIRED("date") ZEND_MOD_REQUIRED("json") ZEND_MOD_REQUIRED("spl") ZEND_MOD_REQUIRED("standard") ZEND_MOD_END }; /* {{{ mongodb_module_entry */ zend_module_entry mongodb_module_entry = { STANDARD_MODULE_HEADER_EX, NULL, mongodb_deps, "mongodb", mongodb_functions, PHP_MINIT(mongodb), PHP_MSHUTDOWN(mongodb), PHP_RINIT(mongodb), PHP_RSHUTDOWN(mongodb), PHP_MINFO(mongodb), PHP_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.3.4/php_phongo.h0000664000175000017500000002124613210321137015314 0ustar jmikolajmikola/* * Copyright 2014-2017 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 PHONGO_H #define PHONGO_H /* External libs */ #include "bson.h" #include "mongoc.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 PHP_MONGODB_VERSION "1.3.4" #define PHP_MONGODB_STABILITY "stable" /* Structure for persisted libmongoc clients. The PID is included to ensure that * processes do not destroy clients created by other processes (relevant for * forking). We avoid using pid_t for Windows compatibility. */ typedef struct { mongoc_client_t *client; int pid; } php_phongo_pclient_t; ZEND_BEGIN_MODULE_GLOBALS(mongodb) char *debug; FILE *debug_fd; bson_mem_vtable_t bsonMemVTable; HashTable pclients; HashTable *subscribers; ZEND_END_MODULE_GLOBALS(mongodb) #if PHP_VERSION_ID >= 70000 # define MONGODB_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mongodb, v) # if defined(ZTS) && defined(COMPILE_DL_MONGODB) ZEND_TSRMLS_CACHE_EXTERN() # endif #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" /* This enum is necessary since mongoc_server_description_type_t is private and * we need to translate strings returned by mongoc_server_description_type() to * Server integer constants. */ typedef enum { PHONGO_SERVER_UNKNOWN = 0, PHONGO_SERVER_STANDALONE = 1, PHONGO_SERVER_MONGOS = 2, PHONGO_SERVER_POSSIBLE_PRIMARY = 3, PHONGO_SERVER_RS_PRIMARY = 4, PHONGO_SERVER_RS_SECONDARY = 5, PHONGO_SERVER_RS_ARBITER = 6, PHONGO_SERVER_RS_OTHER = 7, PHONGO_SERVER_RS_GHOST = 8, PHONGO_SERVER_DESCRIPTION_TYPES = 9, } php_phongo_server_description_type_t; typedef struct { php_phongo_server_description_type_t type; const char *name; } php_phongo_server_description_type_map_t; extern php_phongo_server_description_type_map_t php_phongo_server_description_type_map[]; 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; zend_class_entry* phongo_exception_from_mongoc_domain(uint32_t /* mongoc_error_domain_t */ domain, uint32_t /* mongoc_error_code_t */ code); 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); 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); mongoc_bulk_operation_t* phongo_bulkwrite_init (zend_bool ordered); bool phongo_execute_write (mongoc_client_t *client, const char *namespace, php_phongo_bulkwrite_t *bulk_write, 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, zval *zcommand, zval *zreadPreference, int server_id, zval *return_value, int return_value_used TSRMLS_DC); int phongo_execute_query (mongoc_client_t *client, const char *namespace, zval *zquery, zval *zreadPreference, int server_id, zval *return_value, int return_value_used TSRMLS_DC); 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); php_phongo_server_description_type_t php_phongo_server_description_type(mongoc_server_description_t *sd); void php_phongo_read_preference_prep_tagsets(zval *tagSets TSRMLS_DC); bool php_phongo_read_preference_tags_are_valid(const bson_t *tags); void php_phongo_server_to_zval(zval *retval, 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); void phongo_manager_init(php_phongo_manager_t *manager, const char *uri_string, zval *options, zval *driverOptions TSRMLS_DC); int php_phongo_set_monitoring_callbacks(mongoc_client_t *client); 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_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_decimal128(zval *object, const bson_decimal128_t *decimal 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); #if PHP_VERSION_ID >= 70000 #define PHONGO_CE_FINAL(ce) do { \ ce->ce_flags |= ZEND_ACC_FINAL; \ } while(0); #else #define PHONGO_CE_FINAL(ce) do { \ ce->ce_flags |= ZEND_ACC_FINAL_CLASS; \ } while(0); #endif #define PHONGO_CE_DISABLE_SERIALIZATION(ce) do { \ ce->serialize = zend_class_serialize_deny; \ ce->unserialize = zend_class_unserialize_deny; \ } while(0); #define PHONGO_GET_PROPERTY_HASH_INIT_PROPS(is_debug, intern, props, size) do { \ if (is_debug) { \ ALLOC_HASHTABLE(props); \ zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \ } else if ((intern)->properties) { \ zend_hash_clean((intern)->properties); \ (props) = (intern)->properties; \ } else { \ ALLOC_HASHTABLE(props); \ zend_hash_init((props), (size), NULL, ZVAL_PTR_DTOR, 0); \ (intern)->properties = (props); \ } \ } while(0); #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.3.4/php_phongo_classes.h0000664000175000017500000005015313210321137017030 0ustar jmikolajmikola/* * Copyright 2014-2017 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 PHONGO_CLASSES_H #define PHONGO_CLASSES_H #include "php_phongo_structs.h" /* Export zend_class_entry dependencies, which are initialized in MINIT */ extern zend_class_entry *php_phongo_date_immutable_ce; extern zend_class_entry *php_phongo_json_serializable_ce; #if PHP_VERSION_ID >= 70000 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_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_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_decimal128_t* php_decimal128_fetch_object(zend_object *obj) { return (php_phongo_decimal128_t *)((char *)obj - XtOffsetOf(php_phongo_decimal128_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_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)); } static inline php_phongo_commandfailedevent_t* php_commandfailedevent_fetch_object(zend_object *obj) { return (php_phongo_commandfailedevent_t *)((char *)obj - XtOffsetOf(php_phongo_commandfailedevent_t, std)); } static inline php_phongo_commandstartedevent_t* php_commandstartedevent_fetch_object(zend_object *obj) { return (php_phongo_commandstartedevent_t *)((char *)obj - XtOffsetOf(php_phongo_commandstartedevent_t, std)); } static inline php_phongo_commandsucceededevent_t* php_commandsucceededevent_fetch_object(zend_object *obj) { return (php_phongo_commandsucceededevent_t *)((char *)obj - XtOffsetOf(php_phongo_commandsucceededevent_t, std)); } # 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_DECIMAL128_OBJ_P(zv) (php_decimal128_fetch_object(Z_OBJ_P(zv))) # define Z_JAVASCRIPT_OBJ_P(zv) (php_javascript_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_COMMANDFAILEDEVENT_OBJ_P(zv) (php_commandfailedevent_fetch_object(Z_OBJ_P(zv))) # define Z_COMMANDSTARTEDEVENT_OBJ_P(zv) (php_commandstartedevent_fetch_object(Z_OBJ_P(zv))) # define Z_COMMANDSUCCEEDEDEVENT_OBJ_P(zv) (php_commandsucceededevent_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_DECIMAL128(zo) (php_decimal128_fetch_object(zo)) # define Z_OBJ_JAVASCRIPT(zo) (php_javascript_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)) # define Z_OBJ_COMMANDFAILEDEVENT(zo) (php_commandfailedevent_fetch_object(zo)) # define Z_OBJ_COMMANDSTARTEDEVENT(zo) (php_commandstartedevent_fetch_object(zo)) # define Z_OBJ_COMMANDSUCCEEDEDEVENT(zo) (php_commandsucceededevent_fetch_object(zo)) #else # 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_DECIMAL128_OBJ_P(zv) ((php_phongo_decimal128_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_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_COMMANDFAILEDEVENT_OBJ_P(zv) ((php_phongo_commandfailedevent_t *)zend_object_store_get_object(zv TSRMLS_CC)) # define Z_COMMANDSTARTEDEVENT_OBJ_P(zv) ((php_phongo_commandstartedevent_t *)zend_object_store_get_object(zv TSRMLS_CC)) # define Z_COMMANDSUCCEEDEDEVENT_OBJ_P(zv) ((php_phongo_commandsucceededevent_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_DECIMAL128(zo) ((php_phongo_decimal128_t *)zo) # define Z_OBJ_JAVASCRIPT(zo) ((php_phongo_javascript_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) # define Z_OBJ_COMMANDFAILEDEVENT(zo) ((php_phongo_commandfailedevent_t *)zo) # define Z_OBJ_COMMANDSTARTEDEVENT(zo) ((php_phongo_commandstartedevent_t *)zo) # define Z_OBJ_COMMANDSUCCEEDEDEVENT(zo) ((php_phongo_commandsucceededevent_t *)zo) #endif typedef struct { zend_object_iterator intern; php_phongo_cursor_t *cursor; } php_phongo_cursor_iterator; extern zend_class_entry *php_phongo_command_ce; extern zend_class_entry *php_phongo_cursor_ce; extern zend_class_entry *php_phongo_cursorid_ce; extern zend_class_entry *php_phongo_manager_ce; extern zend_class_entry *php_phongo_query_ce; extern zend_class_entry *php_phongo_readconcern_ce; extern zend_class_entry *php_phongo_readpreference_ce; extern zend_class_entry *php_phongo_server_ce; extern zend_class_entry *php_phongo_bulkwrite_ce; extern zend_class_entry *php_phongo_writeconcern_ce; extern zend_class_entry *php_phongo_writeconcernerror_ce; extern zend_class_entry *php_phongo_writeerror_ce; extern zend_class_entry *php_phongo_writeresult_ce; extern zend_class_entry *php_phongo_exception_ce; extern zend_class_entry *php_phongo_logicexception_ce; extern zend_class_entry *php_phongo_runtimeexception_ce; extern zend_class_entry *php_phongo_unexpectedvalueexception_ce; extern zend_class_entry *php_phongo_invalidargumentexception_ce; extern zend_class_entry *php_phongo_connectionexception_ce; extern zend_class_entry *php_phongo_authenticationexception_ce; extern zend_class_entry *php_phongo_sslconnectionexception_ce; extern zend_class_entry *php_phongo_executiontimeoutexception_ce; extern zend_class_entry *php_phongo_connectiontimeoutexception_ce; extern zend_class_entry *php_phongo_writeexception_ce; extern zend_class_entry *php_phongo_bulkwriteexception_ce; extern zend_class_entry *php_phongo_type_ce; extern zend_class_entry *php_phongo_persistable_ce; extern zend_class_entry *php_phongo_unserializable_ce; extern zend_class_entry *php_phongo_serializable_ce; extern zend_class_entry *php_phongo_binary_ce; extern zend_class_entry *php_phongo_decimal128_ce; extern zend_class_entry *php_phongo_javascript_ce; extern zend_class_entry *php_phongo_maxkey_ce; extern zend_class_entry *php_phongo_minkey_ce; extern zend_class_entry *php_phongo_objectid_ce; extern zend_class_entry *php_phongo_regex_ce; extern zend_class_entry *php_phongo_timestamp_ce; extern zend_class_entry *php_phongo_utcdatetime_ce; extern zend_class_entry *php_phongo_binary_interface_ce; extern zend_class_entry *php_phongo_decimal128_interface_ce; extern zend_class_entry *php_phongo_javascript_interface_ce; extern zend_class_entry *php_phongo_maxkey_interface_ce; extern zend_class_entry *php_phongo_minkey_interface_ce; extern zend_class_entry *php_phongo_objectid_interface_ce; extern zend_class_entry *php_phongo_regex_interface_ce; extern zend_class_entry *php_phongo_timestamp_interface_ce; extern zend_class_entry *php_phongo_utcdatetime_interface_ce; extern zend_class_entry *php_phongo_commandfailedevent_ce; extern zend_class_entry *php_phongo_commandstartedevent_ce; extern zend_class_entry *php_phongo_commandsubscriber_ce; extern zend_class_entry *php_phongo_commandsucceededevent_ce; extern zend_class_entry *php_phongo_subscriber_ce; extern void php_phongo_binary_init_ce(INIT_FUNC_ARGS); extern void php_phongo_decimal128_init_ce(INIT_FUNC_ARGS); extern void php_phongo_javascript_init_ce(INIT_FUNC_ARGS); extern void php_phongo_maxkey_init_ce(INIT_FUNC_ARGS); extern void php_phongo_minkey_init_ce(INIT_FUNC_ARGS); extern void php_phongo_objectid_init_ce(INIT_FUNC_ARGS); extern void php_phongo_persistable_init_ce(INIT_FUNC_ARGS); extern void php_phongo_regex_init_ce(INIT_FUNC_ARGS); extern void php_phongo_serializable_init_ce(INIT_FUNC_ARGS); extern void php_phongo_timestamp_init_ce(INIT_FUNC_ARGS); extern void php_phongo_type_init_ce(INIT_FUNC_ARGS); extern void php_phongo_utcdatetime_init_ce(INIT_FUNC_ARGS); extern void php_phongo_unserializable_init_ce(INIT_FUNC_ARGS); extern void php_phongo_binary_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_decimal128_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_javascript_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_maxkey_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_minkey_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_objectid_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_regex_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_timestamp_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_utcdatetime_interface_init_ce(INIT_FUNC_ARGS); extern void php_phongo_bulkwrite_init_ce(INIT_FUNC_ARGS); extern void php_phongo_command_init_ce(INIT_FUNC_ARGS); extern void php_phongo_cursor_init_ce(INIT_FUNC_ARGS); extern void php_phongo_cursorid_init_ce(INIT_FUNC_ARGS); extern void php_phongo_manager_init_ce(INIT_FUNC_ARGS); extern void php_phongo_query_init_ce(INIT_FUNC_ARGS); extern void php_phongo_readconcern_init_ce(INIT_FUNC_ARGS); extern void php_phongo_readpreference_init_ce(INIT_FUNC_ARGS); extern void php_phongo_server_init_ce(INIT_FUNC_ARGS); extern void php_phongo_writeconcern_init_ce(INIT_FUNC_ARGS); extern void php_phongo_writeconcernerror_init_ce(INIT_FUNC_ARGS); extern void php_phongo_writeerror_init_ce(INIT_FUNC_ARGS); extern void php_phongo_writeresult_init_ce(INIT_FUNC_ARGS); extern void php_phongo_authenticationexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_bulkwriteexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_connectionexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_connectiontimeoutexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_exception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_executiontimeoutexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_invalidargumentexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_logicexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_runtimeexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_sslconnectionexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_unexpectedvalueexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_writeexception_init_ce(INIT_FUNC_ARGS); extern void php_phongo_commandfailedevent_init_ce(INIT_FUNC_ARGS); extern void php_phongo_commandstartedevent_init_ce(INIT_FUNC_ARGS); extern void php_phongo_commandsubscriber_init_ce(INIT_FUNC_ARGS); extern void php_phongo_commandsucceededevent_init_ce(INIT_FUNC_ARGS); extern void php_phongo_subscriber_init_ce(INIT_FUNC_ARGS); /* Shared function entries for disabling constructors and unserialize() */ PHP_FUNCTION(MongoDB_disabled___construct); PHP_FUNCTION(MongoDB_disabled___wakeup); #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.3.4/php_phongo_structs.h0000664000175000017500000001412513210321137017101 0ustar jmikolajmikola/* * Copyright 2015-2017 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 PHONGO_STRUCTS_H #define PHONGO_STRUCTS_H #include #include "php_bson.h" #if PHP_VERSION_ID >= 70000 # define PHONGO_ZEND_OBJECT_PRE # define PHONGO_ZEND_OBJECT_POST zend_object std; # define PHONGO_STRUCT_ZVAL zval #else # define PHONGO_ZEND_OBJECT_PRE zend_object std; # define PHONGO_ZEND_OBJECT_POST # define PHONGO_STRUCT_ZVAL zval* #endif typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_bulk_operation_t *bulk; size_t num_ops; bool ordered; int bypass; char *database; char *collection; bool executed; PHONGO_ZEND_OBJECT_POST } php_phongo_bulkwrite_t; typedef struct { PHONGO_ZEND_OBJECT_PRE bson_t *bson; PHONGO_ZEND_OBJECT_POST } php_phongo_command_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_cursor_t *cursor; mongoc_client_t *client; int server_id; php_phongo_bson_state visitor_data; int got_iterator; long current; char *database; char *collection; PHONGO_STRUCT_ZVAL query; PHONGO_STRUCT_ZVAL command; PHONGO_STRUCT_ZVAL read_preference; PHONGO_ZEND_OBJECT_POST } php_phongo_cursor_t; typedef struct { PHONGO_ZEND_OBJECT_PRE int64_t id; PHONGO_ZEND_OBJECT_POST } php_phongo_cursorid_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_client_t *client; PHONGO_ZEND_OBJECT_POST } php_phongo_manager_t; typedef struct { PHONGO_ZEND_OBJECT_PRE bson_t *filter; bson_t *opts; mongoc_read_concern_t *read_concern; uint32_t max_await_time_ms; PHONGO_ZEND_OBJECT_POST } php_phongo_query_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_read_concern_t *read_concern; PHONGO_ZEND_OBJECT_POST } php_phongo_readconcern_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_read_prefs_t *read_preference; PHONGO_ZEND_OBJECT_POST } php_phongo_readpreference_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_client_t *client; int server_id; PHONGO_ZEND_OBJECT_POST } php_phongo_server_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_write_concern_t *write_concern; PHONGO_ZEND_OBJECT_POST } php_phongo_writeconcern_t; typedef struct { PHONGO_ZEND_OBJECT_PRE int code; char *message; PHONGO_STRUCT_ZVAL info; PHONGO_ZEND_OBJECT_POST } php_phongo_writeconcernerror_t; typedef struct { PHONGO_ZEND_OBJECT_PRE int code; char *message; PHONGO_STRUCT_ZVAL info; uint32_t index; PHONGO_ZEND_OBJECT_POST } php_phongo_writeerror_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_write_concern_t *write_concern; bson_t *reply; mongoc_client_t *client; int server_id; PHONGO_ZEND_OBJECT_POST } php_phongo_writeresult_t; typedef struct { PHONGO_ZEND_OBJECT_PRE char *data; int data_len; uint8_t type; HashTable *properties; PHONGO_ZEND_OBJECT_POST } php_phongo_binary_t; typedef struct { PHONGO_ZEND_OBJECT_PRE bool initialized; bson_decimal128_t decimal; HashTable *properties; PHONGO_ZEND_OBJECT_POST } php_phongo_decimal128_t; typedef struct { PHONGO_ZEND_OBJECT_PRE char *code; size_t code_len; bson_t *scope; HashTable *properties; PHONGO_ZEND_OBJECT_POST } php_phongo_javascript_t; typedef struct { PHONGO_ZEND_OBJECT_PRE PHONGO_ZEND_OBJECT_POST } php_phongo_maxkey_t; typedef struct { PHONGO_ZEND_OBJECT_PRE PHONGO_ZEND_OBJECT_POST } php_phongo_minkey_t; typedef struct { PHONGO_ZEND_OBJECT_PRE bool initialized; char oid[25]; HashTable *properties; PHONGO_ZEND_OBJECT_POST } php_phongo_objectid_t; typedef struct { PHONGO_ZEND_OBJECT_PRE char *pattern; int pattern_len; char *flags; int flags_len; HashTable *properties; PHONGO_ZEND_OBJECT_POST } php_phongo_regex_t; typedef struct { PHONGO_ZEND_OBJECT_PRE bool initialized; uint32_t increment; uint32_t timestamp; HashTable *properties; PHONGO_ZEND_OBJECT_POST } php_phongo_timestamp_t; typedef struct { PHONGO_ZEND_OBJECT_PRE bool initialized; int64_t milliseconds; HashTable *properties; PHONGO_ZEND_OBJECT_POST } php_phongo_utcdatetime_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_client_t *client; char *command_name; uint32_t server_id; uint64_t operation_id; uint64_t request_id; uint64_t duration_micros; PHONGO_STRUCT_ZVAL z_error; PHONGO_ZEND_OBJECT_POST } php_phongo_commandfailedevent_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_client_t *client; char *command_name; uint32_t server_id; uint64_t operation_id; uint64_t request_id; bson_t *command; char *database_name; PHONGO_ZEND_OBJECT_POST } php_phongo_commandstartedevent_t; typedef struct { PHONGO_ZEND_OBJECT_PRE mongoc_client_t *client; char *command_name; uint32_t server_id; uint64_t operation_id; uint64_t request_id; uint64_t duration_micros; bson_t *reply; PHONGO_ZEND_OBJECT_POST } php_phongo_commandsucceededevent_t; #undef PHONGO_ZEND_OBJECT_PRE #undef PHONGO_ZEND_OBJECT_POST #undef PHONGO_STRUCT_ZVAL #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 */