提交 951f1599 authored 作者: Daniel Swarbrick's avatar Daniel Swarbrick

update mongo-c-driver to 0.5.2

上级 3ba5c729
...@@ -2,8 +2,8 @@ include ../../../../build/modmake.rules ...@@ -2,8 +2,8 @@ include ../../../../build/modmake.rules
MONGODB_DRIVER=./driver/src MONGODB_DRIVER=./driver/src
LOCAL_CFLAGS=-I$(MONGODB_DRIVER) LOCAL_CFLAGS=-I$(MONGODB_DRIVER)
LOCAL_OBJS=$(MONGODB_DRIVER)/md5.o \ LOCAL_OBJS=$(MONGODB_DRIVER)/encoding.o $(MONGODB_DRIVER)/env_posix.o \
$(MONGODB_DRIVER)/mongo.o $(MONGODB_DRIVER)/net.o \ $(MONGODB_DRIVER)/bson.o $(MONGODB_DRIVER)/md5.o \
$(MONGODB_DRIVER)/bson.o $(MONGODB_DRIVER)/numbers.o $(MONGODB_DRIVER)/encoding.o \ $(MONGODB_DRIVER)/mongo.o $(MONGODB_DRIVER)/numbers.o
local_depend: $(LOCAL_OBJS) local_depend: $(LOCAL_OBJS)
# MongoDB C Driver History # MongoDB C Driver History
## 0.5.2
2012-5-4
* Validate collection and database names on insert.
* Validate insert limits using max BSON size.
* Support getaddrinfo and SO_RCVTIMEO and SO_SNDTIMEO on Windows.
* Store errno/WSAGetLastError() on errors.
* Various bug fixes and refactorings.
* Update error reporting docs.
## 0.5.1
* Env for POSIX, WIN32, and standard C.
* Various bug fixes.
## 0.5
2012-3-31
* Separate cursor-specific errors into their own enum: mongo_cursor_error_t.
* Catch $err return on bad queries and store the result in conn->getlasterrorcode
and conn->getlasterrstr.
* On queries that return $err, set cursor->err to MONGO_CURSOR_QUERY_FAIL.
* When passing bad BSON to a cursor object, set cursor->err to MONGO_CURSOR_BSON_ERROR,
and store the specific BSON error on the conn->err field.
* Remove bson_copy_basic().
* bson_copy() will copy finished bson objects only.
* bson_copy() returns BSON_OK on success and BSON_ERROR on failure.
* Added a Makefile for easy compile and install on Linux and OS X.
* Replica set connect fixes.
## 0.4 ## 0.4
THIS RELEASE INCLUDES NUMEROUS BACKWARD-BREAKING CHANGES. THIS RELEASE INCLUDES NUMEROUS BACKWARD-BREAKING CHANGES.
......
...@@ -12,9 +12,9 @@ Until the 1.0 release, this driver should be considered alpha. Keep in mind that ...@@ -12,9 +12,9 @@ Until the 1.0 release, this driver should be considered alpha. Keep in mind that
# Building # Building
First check out the version you want to build. *Always build from a particular tag, since HEAD may be First check out the version you want to build. *Always build from a particular tag, since HEAD may be
a work in progress.* For example, to build version 0.4, run: a work in progress.* For example, to build version 0.5.2, run:
git checkout v0.4 git checkout v0.5.2
You can then build the driver with scons: You can then build the driver with scons:
......
# -*- mode: python; -*-
VERSION = "0.4"
# --- options ----
AddOption('--test-server',
dest='test_server',
default='127.0.0.1',
type='string',
nargs=1,
action='store',
help='IP address of server to use for testing')
AddOption('--seed-start-port',
dest='seed_start_port',
default=30000,
type='int',
nargs=1,
action='store',
help='IP address of server to use for testing')
AddOption('--c99',
dest='use_c99',
default=False,
action='store_true',
help='Compile with c99 (recommended for gcc)')
AddOption('--d',
dest='optimize',
default=True,
action='store_false',
help='disable optimizations')
AddOption('--use-platform',
dest='compile_platform',
default='GENERIC',
type='string',
nargs=1,
action='store',
help='Compile for a specific platform to take advantage '
' of particular system features. For the moment, this include timeouts only.'
' Current options include LINUX, '
' GENERIC, and CUSTOM. If you specific CUSTOM, you must place a'
' system-specific implementation of net.h and net.c in src/platform/custom/')
import os, sys
env = Environment( ENV=os.environ )
# ---- Docs ----
def build_docs(env, target, source):
buildscript_path = os.path.join(os.path.abspath("docs"))
sys.path.insert(0, buildscript_path)
import buildscripts
from buildscripts import docs
docs.main()
env.Alias("docs", [], [build_docs])
env.AlwaysBuild("docs")
# ---- Platforms ----
PLATFORM_TEST_DIR = None
if "LINUX" == GetOption('compile_platform'):
env.Append( CPPFLAGS=" -D_MONGO_USE_LINUX_SYSTEM" )
NET_LIB = "src/platform/linux/net.c"
PLATFORM_TEST_DIR = "test/platform/linux/"
PLATFORM_TESTS = [ "timeouts" ]
elif "CUSTOM" == GetOption('compile_platform'):
env.Append( CPPFLAGS=" -D_MONGO_USE_CUSTOM_SYSTEM" )
NET_LIB = "src/platform/custom/net.c"
else:
NET_LIB = "src/net.c"
# ---- Libraries ----
if os.sys.platform in ["darwin", "linux2"]:
env.Append( CPPFLAGS=" -pedantic -Wall -ggdb -DMONGO_HAVE_STDINT" )
env.Append( CPPPATH=["/opt/local/include/"] )
env.Append( LIBPATH=["/opt/local/lib/"] )
if GetOption('use_c99'):
env.Append( CFLAGS=" -std=c99 " )
env.Append( CXXDEFINES="MONGO_HAVE_STDINT" )
else:
env.Append( CFLAGS=" -ansi " )
if GetOption('optimize'):
env.Append( CPPFLAGS=" -O3 " )
# -O3 benchmarks *significantly* faster than -O2 when disabling networking
elif 'win32' == os.sys.platform:
env.Append( LIBS='ws2_32' )
#we shouldn't need these options in c99 mode
if not GetOption('use_c99'):
conf = Configure(env)
if not conf.CheckType('int64_t'):
if conf.CheckType('int64_t', '#include <stdint.h>\n'):
conf.env.Append( CPPDEFINES="MONGO_HAVE_STDINT" )
elif conf.CheckType('int64_t', '#include <unistd.h>\n'):
conf.env.Append( CPPDEFINES="MONGO_HAVE_UNISTD" )
elif conf.CheckType('__int64'):
conf.env.Append( CPPDEFINES="MONGO_USE__INT64" )
elif conf.CheckType('long long int'):
conf.env.Append( CPPDEFINES="MONGO_USE_LONG_LONG_INT" )
else:
print "*** what is your 64 bit int type? ****"
Exit(1)
env = conf.Finish()
have_libjson = False
conf = Configure(env)
if conf.CheckLib('json'):
have_libjson = True
env = conf.Finish()
if sys.byteorder == 'big':
env.Append( CPPDEFINES="MONGO_BIG_ENDIAN" )
env.Append( CPPPATH=["src/"] )
coreFiles = ["src/md5.c" ]
mFiles = [ "src/mongo.c", NET_LIB, "src/gridfs.c"]
bFiles = [ "src/bson.c", "src/numbers.c", "src/encoding.c"]
mLibFiles = coreFiles + mFiles + bFiles
bLibFiles = coreFiles + bFiles
m = env.Library( "mongoc" , mLibFiles )
b = env.Library( "bson" , bLibFiles )
env.Default( env.Alias( "lib" , [ m[0] , b[0] ] ) )
if os.sys.platform == "linux2":
env.Append( SHLINKFLAGS="-shared -Wl,-soname,libmongoc.so." + VERSION )
env.Append( SHLINKFLAGS = "-shared -Wl,-soname,libbson.so." + VERSION )
dynm = env.SharedLibrary( "mongoc" , mLibFiles )
dynb = env.SharedLibrary( "bson" , bLibFiles )
env.Default( env.Alias( "sharedlib" , [ dynm[0] , dynb[0] ] ) )
# ---- Benchmarking ----
benchmarkEnv = env.Clone()
benchmarkEnv.Append( CPPDEFINES=[('TEST_SERVER', r'\"%s\"'%GetOption('test_server')),
('SEED_START_PORT', r'%d'%GetOption('seed_start_port'))] )
benchmarkEnv.Append( LIBS=[m, b] )
benchmarkEnv.Prepend( LIBPATH=["."] )
benchmarkEnv.Program( "benchmark" , [ "test/benchmark.c"] )
# ---- Tests ----
testEnv = benchmarkEnv.Clone()
testCoreFiles = [ ]
def run_tests( root, tests ):
for name in tests:
filename = "%s/%s.c" % (root, name)
exe = "test_" + name
test = testEnv.Program( exe , testCoreFiles + [filename] )
test_alias = testEnv.Alias('test', [test], test[0].abspath + ' 2> ' + os.path.devnull)
AlwaysBuild(test_alias)
tests = Split("sizes resize endian_swap bson bson_subobject simple update errors "
"count_delete auth gridfs validate examples helpers oid functions cursors replica_set")
# Run standard tests
run_tests("test", tests)
# Run platform tests
if not PLATFORM_TEST_DIR is None:
run_tests( PLATFORM_TEST_DIR, PLATFORM_TESTS )
if have_libjson:
tests.append('json')
testEnv.Append( LIBS=["json"] )
# special case for cpptest
test = testEnv.Program( 'test_cpp' , testCoreFiles + ['test/cpptest.cpp'] )
test_alias = testEnv.Alias('test', [test], test[0].abspath + ' 2> '+ os.path.devnull)
AlwaysBuild(test_alias)
/* /*
* Copyright 2009-2011 10gen, Inc. * Copyright 2009-2012 10gen, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
......
/* /*
* Copyright 2009-2011 10gen, Inc. * Copyright 2009-2012 10gen, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef _BSON_ENCODING_H_ #ifndef BSON_ENCODING_H_
#define _BSON_ENCODING_H_ #define BSON_ENCODING_H_
MONGO_EXTERN_C_START MONGO_EXTERN_C_START
......
/** @file net.h */ /** @file env.h */
/* Copyright 2009-2011 10gen Inc. /* Copyright 2009-2012 10gen Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,42 +16,24 @@ ...@@ -16,42 +16,24 @@
*/ */
/* Header for generic net.h */ /* Header for generic net.h */
#ifndef _MONGO_NET_H_ #ifndef MONGO_ENV_H_
#define _MONGO_NET_H_ #define MONGO_ENV_H_
#include "mongo.h" #include "mongo.h"
#ifdef _WIN32
#include <windows.h>
#include <winsock.h>
#define mongo_close_socket(sock) ( closesocket(sock) )
typedef int socklen_t;
#else
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#define mongo_close_socket(sock) ( close(sock) )
#endif
#ifndef _WIN32
#include <unistd.h>
#endif
#if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1
#define _MONGO_USE_GETADDRINFO
#endif
MONGO_EXTERN_C_START MONGO_EXTERN_C_START
/* This is a no-op in the generic implementation. */ /* This is a no-op in the generic implementation. */
int mongo_set_socket_op_timeout( mongo *conn, int millis ); int mongo_env_set_socket_op_timeout( mongo *conn, int millis );
int mongo_read_socket( mongo *conn, void *buf, int len ); int mongo_env_read_socket( mongo *conn, void *buf, int len );
int mongo_write_socket( mongo *conn, const void *buf, int len ); int mongo_env_write_socket( mongo *conn, const void *buf, int len );
int mongo_socket_connect( mongo *conn, const char *host, int port ); int mongo_env_socket_connect( mongo *conn, const char *host, int port );
/* Initialize socket services */
MONGO_EXPORT int mongo_env_sock_init( void );
/* Close a socket */
MONGO_EXPORT int mongo_env_close_socket( int socket );
MONGO_EXTERN_C_END MONGO_EXTERN_C_END
#endif #endif
/* net.c */ /* env_posix.c */
/* Copyright 2009-2011 10gen Inc. /* Copyright 2009-2012 10gen Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -15,16 +15,47 @@ ...@@ -15,16 +15,47 @@
* limitations under the License. * limitations under the License.
*/ */
/* Implementation for Linux version of net.h */ /* Networking and other niceties for POSIX systems. */
#include "net.h" #include "env.h"
#include "mongo.h"
#include <string.h> #include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef NI_MAXSERV
# define NI_MAXSERV 32
#endif
int mongo_env_close_socket( int socket ) {
return close( socket );
}
int mongo_env_sock_init( void ) {
return 0;
}
int mongo_write_socket( mongo *conn, const void *buf, int len ) { int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
const char *cbuf = buf; const char *cbuf = buf;
#ifdef __APPLE__
int flags = 0;
#else
int flags = MSG_NOSIGNAL;
#endif
while ( len ) { while ( len ) {
int sent = send( conn->sock, cbuf, len, 0 ); int sent = send( conn->sock, cbuf, len, flags );
if ( sent == -1 ) { if ( sent == -1 ) {
conn->err = MONGO_IO_ERROR; if (errno == EPIPE)
conn->connected = 0;
__mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
return MONGO_ERROR; return MONGO_ERROR;
} }
cbuf += sent; cbuf += sent;
...@@ -34,12 +65,12 @@ int mongo_write_socket( mongo *conn, const void *buf, int len ) { ...@@ -34,12 +65,12 @@ int mongo_write_socket( mongo *conn, const void *buf, int len ) {
return MONGO_OK; return MONGO_OK;
} }
int mongo_read_socket( mongo *conn, void *buf, int len ) { int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
char *cbuf = buf; char *cbuf = buf;
while ( len ) { while ( len ) {
int sent = recv( conn->sock, cbuf, len, 0 ); int sent = recv( conn->sock, cbuf, len, 0 );
if ( sent == 0 || sent == -1 ) { if ( sent == 0 || sent == -1 ) {
conn->err = MONGO_IO_ERROR; __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
return MONGO_ERROR; return MONGO_ERROR;
} }
cbuf += sent; cbuf += sent;
...@@ -49,135 +80,86 @@ int mongo_read_socket( mongo *conn, void *buf, int len ) { ...@@ -49,135 +80,86 @@ int mongo_read_socket( mongo *conn, void *buf, int len ) {
return MONGO_OK; return MONGO_OK;
} }
static int mongo_create_socket( mongo *conn ) { int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
int fd;
if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) {
conn->err = MONGO_CONN_NO_SOCKET;
return MONGO_ERROR;
}
conn->sock = fd;
return MONGO_OK;
}
static int mongo_set_blocking_status( mongo *conn ) {
int flags;
int blocking;
blocking = ( conn->conn_timeout_ms == 0 );
if( blocking )
return MONGO_OK;
else {
if( ( flags = fcntl( conn->sock, F_GETFL ) ) == -1 ) {
conn->err = MONGO_IO_ERROR;
mongo_close_socket( conn->sock );
return MONGO_ERROR;
}
flags |= O_NONBLOCK;
if( ( flags = fcntl( conn->sock, F_SETFL, flags ) ) == -1 ) {
conn->err = MONGO_IO_ERROR;
mongo_close_socket( conn->sock );
return MONGO_ERROR;
}
}
return MONGO_OK;
}
int mongo_set_socket_op_timeout( mongo *conn, int millis ) {
struct timeval tv; struct timeval tv;
tv.tv_sec = millis / 1000; tv.tv_sec = millis / 1000;
tv.tv_usec = ( millis % 1000 ) * 1000; tv.tv_usec = ( millis % 1000 ) * 1000;
if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) { if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) {
conn->err = MONGO_IO_ERROR; conn->err = MONGO_IO_ERROR;
__mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.", errno );
return MONGO_ERROR; return MONGO_ERROR;
} }
if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) { if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) {
conn->err = MONGO_IO_ERROR; __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.", errno );
return MONGO_ERROR; return MONGO_ERROR;
} }
return MONGO_OK; return MONGO_OK;
} }
#ifdef _MONGO_USE_GETADDRINFO int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
int mongo_socket_connect( mongo *conn, const char *host, int port ) { char port_str[NI_MAXSERV];
int status;
struct addrinfo *addrs = NULL; struct addrinfo ai_hints;
struct addrinfo hints; struct addrinfo *ai_list = NULL;
int flag = 1; struct addrinfo *ai_ptr = NULL;
char port_str[12];
int ret;
conn->sock = 0; conn->sock = 0;
conn->connected = 0; conn->connected = 0;
sprintf(port_str,"%d",port);
memset( &hints, 0, sizeof( hints ) ); bson_sprintf( port_str, "%d", port );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
sprintf( port_str, "%d", port );
if( mongo_create_socket( conn ) != MONGO_OK ) memset( &ai_hints, 0, sizeof( ai_hints ) );
return MONGO_ERROR; #ifdef AI_ADDRCONFIG
ai_hints.ai_flags = AI_ADDRCONFIG;
#endif
ai_hints.ai_family = AF_UNSPEC;
ai_hints.ai_socktype = SOCK_STREAM;
if( getaddrinfo( host, port_str, &hints, &addrs ) != 0 ) { status = getaddrinfo( host, port_str, &ai_hints, &ai_list );
bson_errprintf( "getaddrinfo failed: %s", gai_strerror( ret ) ); if ( status != 0 ) {
bson_errprintf( "getaddrinfo failed: %s", gai_strerror( status ) );
conn->err = MONGO_CONN_ADDR_FAIL; conn->err = MONGO_CONN_ADDR_FAIL;
return MONGO_ERROR; return MONGO_ERROR;
} }
if ( connect( conn->sock, addrs->ai_addr, addrs->ai_addrlen ) == -1 ) { for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) {
mongo_close_socket( conn->sock ); conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol );
freeaddrinfo( addrs ); if ( conn->sock < 0 ) {
conn->err = MONGO_CONN_FAIL; conn->sock = 0;
return MONGO_ERROR; continue;
} }
setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * )&flag, sizeof( flag ) ); status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen );
if( conn->op_timeout_ms > 0 ) if ( status != 0 ) {
mongo_set_socket_op_timeout( conn, conn->op_timeout_ms ); mongo_env_close_socket( conn->sock );
conn->sock = 0;
conn->connected = 1; continue;
freeaddrinfo( addrs ); }
return MONGO_OK; if ( ai_ptr->ai_protocol == IPPROTO_TCP ) {
}
#else
int mongo_socket_connect( mongo *conn, const char *host, int port ) {
struct sockaddr_in sa;
socklen_t addressSize;
int flag = 1; int flag = 1;
if( mongo_create_socket( conn ) != MONGO_OK ) setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY,
return MONGO_ERROR; ( void * ) &flag, sizeof( flag ) );
if ( conn->op_timeout_ms > 0 )
mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
}
memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) ); conn->connected = 1;
sa.sin_family = AF_INET; break;
sa.sin_port = htons( port ); }
sa.sin_addr.s_addr = inet_addr( host );
addressSize = sizeof( sa );
if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) { freeaddrinfo( ai_list );
mongo_close_socket( conn->sock );
conn->connected = 0; if ( ! conn->connected ) {
conn->sock = 0;
conn->err = MONGO_CONN_FAIL; conn->err = MONGO_CONN_FAIL;
return MONGO_ERROR; return MONGO_ERROR;
} }
setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) );
if( conn->op_timeout_ms > 0 )
mongo_set_socket_op_timeout( conn, conn->op_timeout_ms );
conn->connected = 1;
return MONGO_OK; return MONGO_OK;
} }
#endif
/* net.c */ /* env_standard.c */
/* Copyright 2009-2011 10gen Inc. /* Copyright 2009-2012 10gen Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -15,15 +15,60 @@ ...@@ -15,15 +15,60 @@
* limitations under the License. * limitations under the License.
*/ */
/* Implementation for generic version of net.h */ /* Vanilla networking designed to work on all systems. */
#include "net.h" #include "env.h"
#include <errno.h>
#include <string.h> #include <string.h>
int mongo_write_socket( mongo *conn, const void *buf, int len ) { #ifdef _WIN32
#ifdef _MSC_VER
#include <ws2tcpip.h> // send,recv,socklen_t etc
#include <wspiapi.h> // addrinfo
#else
#include <windows.h>
#include <winsock.h>
typedef int socklen_t;
#endif
#else
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#ifndef NI_MAXSERV
# define NI_MAXSERV 32
#endif
int mongo_env_close_socket( int socket ) {
#ifdef _WIN32
return closesocket( socket );
#else
return close( socket );
#endif
}
int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
const char *cbuf = buf; const char *cbuf = buf;
#ifdef _WIN32
int flags = 0;
#else
#ifdef __APPLE__
int flags = 0;
#else
int flags = MSG_NOSIGNAL;
#endif
#endif
while ( len ) { while ( len ) {
int sent = send( conn->sock, cbuf, len, 0 ); int sent = send( conn->sock, cbuf, len, flags );
if ( sent == -1 ) { if ( sent == -1 ) {
if (errno == EPIPE)
conn->connected = 0;
conn->err = MONGO_IO_ERROR; conn->err = MONGO_IO_ERROR;
return MONGO_ERROR; return MONGO_ERROR;
} }
...@@ -34,7 +79,7 @@ int mongo_write_socket( mongo *conn, const void *buf, int len ) { ...@@ -34,7 +79,7 @@ int mongo_write_socket( mongo *conn, const void *buf, int len ) {
return MONGO_OK; return MONGO_OK;
} }
int mongo_read_socket( mongo *conn, void *buf, int len ) { int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
char *cbuf = buf; char *cbuf = buf;
while ( len ) { while ( len ) {
int sent = recv( conn->sock, cbuf, len, 0 ); int sent = recv( conn->sock, cbuf, len, 0 );
...@@ -50,29 +95,20 @@ int mongo_read_socket( mongo *conn, void *buf, int len ) { ...@@ -50,29 +95,20 @@ int mongo_read_socket( mongo *conn, void *buf, int len ) {
} }
/* This is a no-op in the generic implementation. */ /* This is a no-op in the generic implementation. */
int mongo_set_socket_op_timeout( mongo *conn, int millis ) { int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
return MONGO_OK; return MONGO_OK;
} }
static int mongo_create_socket( mongo *conn ) { int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
int fd;
if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) {
conn->err = MONGO_CONN_NO_SOCKET;
return MONGO_ERROR;
}
conn->sock = fd;
return MONGO_OK;
}
int mongo_socket_connect( mongo *conn, const char *host, int port ) {
struct sockaddr_in sa; struct sockaddr_in sa;
socklen_t addressSize; socklen_t addressSize;
int flag = 1; int flag = 1;
if( mongo_create_socket( conn ) != MONGO_OK ) if ( ( conn->sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
conn->sock = 0;
conn->err = MONGO_CONN_NO_SOCKET;
return MONGO_ERROR; return MONGO_ERROR;
}
memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) ); memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) );
sa.sin_family = AF_INET; sa.sin_family = AF_INET;
...@@ -81,7 +117,7 @@ int mongo_socket_connect( mongo *conn, const char *host, int port ) { ...@@ -81,7 +117,7 @@ int mongo_socket_connect( mongo *conn, const char *host, int port ) {
addressSize = sizeof( sa ); addressSize = sizeof( sa );
if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) { if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) {
mongo_close_socket( conn->sock ); mongo_env_close_socket( conn->sock );
conn->connected = 0; conn->connected = 0;
conn->sock = 0; conn->sock = 0;
conn->err = MONGO_CONN_FAIL; conn->err = MONGO_CONN_FAIL;
...@@ -89,10 +125,44 @@ int mongo_socket_connect( mongo *conn, const char *host, int port ) { ...@@ -89,10 +125,44 @@ int mongo_socket_connect( mongo *conn, const char *host, int port ) {
} }
setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) ); setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) );
if( conn->op_timeout_ms > 0 ) if( conn->op_timeout_ms > 0 )
mongo_set_socket_op_timeout( conn, conn->op_timeout_ms ); mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
conn->connected = 1; conn->connected = 1;
return MONGO_OK; return MONGO_OK;
} }
MONGO_EXPORT int mongo_env_sock_init( void ) {
#if defined(_WIN32)
WSADATA wsaData;
WORD wVers;
#elif defined(SIGPIPE)
struct sigaction act;
#endif
static int called_once;
static int retval;
if (called_once) return retval;
called_once = 1;
#if defined(_WIN32)
wVers = MAKEWORD(1, 1);
retval = (WSAStartup(wVers, &wsaData) == 0);
#elif defined(MACINTOSH)
GUSISetup(GUSIwithInternetSockets);
retval = 1;
#elif defined(SIGPIPE)
retval = 1;
if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) < 0)
retval = 0;
else if (act.sa_handler == SIG_DFL) {
act.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) < 0)
retval = 0;
}
#endif
return retval;
}
/* env_win32.c */
/* Copyright 2009-2012 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Networking and other niceties for WIN32. */
#include "env.h"
#include "mongo.h"
#include <string.h>
#ifdef _MSC_VER
#include <ws2tcpip.h> // send,recv,socklen_t etc
#include <wspiapi.h> // addrinfo
#else
#include <windows.h>
#include <winsock.h>
typedef int socklen_t;
#endif
#ifndef NI_MAXSERV
# define NI_MAXSERV 32
#endif
static void mongo_clear_errors( mongo *conn ) {
conn->err = 0;
memset( conn->errstr, 0, MONGO_ERR_LEN );
}
int mongo_env_close_socket( int socket ) {
return closesocket( socket );
}
int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
const char *cbuf = buf;
int flags = 0;
while ( len ) {
int sent = send( conn->sock, cbuf, len, flags );
if ( sent == -1 ) {
__mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
conn->connected = 0;
return MONGO_ERROR;
}
cbuf += sent;
len -= sent;
}
return MONGO_OK;
}
int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
char *cbuf = buf;
while ( len ) {
int sent = recv( conn->sock, cbuf, len, 0 );
if ( sent == 0 || sent == -1 ) {
__mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
return MONGO_ERROR;
}
cbuf += sent;
len -= sent;
}
return MONGO_OK;
}
int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&millis,
sizeof( millis ) ) == -1 ) {
__mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.",
WSAGetLastError() );
return MONGO_ERROR;
}
if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&millis,
sizeof( millis ) ) == -1 ) {
__mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.",
WSAGetLastError() );
return MONGO_ERROR;
}
return MONGO_OK;
}
int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
char port_str[NI_MAXSERV];
char errstr[MONGO_ERR_LEN];
int status;
struct addrinfo ai_hints;
struct addrinfo *ai_list = NULL;
struct addrinfo *ai_ptr = NULL;
conn->sock = 0;
conn->connected = 0;
bson_sprintf( port_str, "%d", port );
memset( &ai_hints, 0, sizeof( ai_hints ) );
ai_hints.ai_family = AF_UNSPEC;
ai_hints.ai_socktype = SOCK_STREAM;
ai_hints.ai_protocol = IPPROTO_TCP;
status = getaddrinfo( host, port_str, &ai_hints, &ai_list );
if ( status != 0 ) {
bson_sprintf( errstr, "getaddrinfo failed with error %d", status );
__mongo_set_error( conn, MONGO_CONN_ADDR_FAIL, errstr, WSAGetLastError() );
return MONGO_ERROR;
}
for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) {
conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype,
ai_ptr->ai_protocol );
if ( conn->sock < 0 ) {
__mongo_set_error( conn, MONGO_SOCKET_ERROR, "socket() failed",
WSAGetLastError() );
conn->sock = 0;
continue;
}
status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen );
if ( status != 0 ) {
__mongo_set_error( conn, MONGO_SOCKET_ERROR, "connect() failed",
WSAGetLastError() );
mongo_env_close_socket( conn->sock );
conn->sock = 0;
continue;
}
if ( ai_ptr->ai_protocol == IPPROTO_TCP ) {
int flag = 1;
setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY,
( void * ) &flag, sizeof( flag ) );
if ( conn->op_timeout_ms > 0 )
mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
}
conn->connected = 1;
break;
}
freeaddrinfo( ai_list );
if ( ! conn->connected ) {
conn->err = MONGO_CONN_FAIL;
return MONGO_ERROR;
}
else {
mongo_clear_errors( conn );
return MONGO_OK;
}
}
MONGO_EXPORT int mongo_env_sock_init( void ) {
WSADATA wsaData;
WORD wVers;
static int called_once;
static int retval;
if (called_once) return retval;
called_once = 1;
wVers = MAKEWORD(1, 1);
retval = (WSAStartup(wVers, &wsaData) == 0);
return retval;
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* */ * */
/* Copyright 2009-2011 10gen Inc. /* Copyright 2009-2012 10gen Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#include "mongo.h" #include "mongo.h"
#ifndef GRIDFS_INCLUDED #ifndef MONGO_GRIDFS_H_
#define GRIDFS_INCLUDED #define MONGO_GRIDFS_H_
enum {DEFAULT_CHUNK_SIZE = 256 * 1024}; enum {DEFAULT_CHUNK_SIZE = 256 * 1024};
...@@ -51,6 +51,12 @@ typedef struct { ...@@ -51,6 +51,12 @@ typedef struct {
int pending_len; /**> Length of pending_data buffer */ int pending_len; /**> Length of pending_data buffer */
} gridfile; } gridfile;
MONGO_EXPORT gridfs* gridfs_create();
MONGO_EXPORT void gridfs_dispose(gridfs* gfs);
MONGO_EXPORT gridfile* gridfile_create();
MONGO_EXPORT void gridfile_dispose(gridfile* gf);
MONGO_EXPORT void gridfile_get_descriptor(gridfile* gf, bson* out);
/** /**
* Initializes a GridFS object * Initializes a GridFS object
* @param client - db connection * @param client - db connection
...@@ -60,7 +66,7 @@ typedef struct { ...@@ -60,7 +66,7 @@ typedef struct {
* *
* @return - MONGO_OK or MONGO_ERROR. * @return - MONGO_OK or MONGO_ERROR.
*/ */
int gridfs_init( mongo *client, const char *dbname, MONGO_EXPORT int gridfs_init( mongo *client, const char *dbname,
const char *prefix, gridfs *gfs ); const char *prefix, gridfs *gfs );
/** /**
...@@ -69,7 +75,7 @@ int gridfs_init( mongo *client, const char *dbname, ...@@ -69,7 +75,7 @@ int gridfs_init( mongo *client, const char *dbname,
* *
* @param gfs a grid * @param gfs a grid
*/ */
void gridfs_destroy( gridfs *gfs ); MONGO_EXPORT void gridfs_destroy( gridfs *gfs );
/** /**
* Initializes a gridfile for writing incrementally with gridfs_write_buffer. * Initializes a gridfile for writing incrementally with gridfs_write_buffer.
...@@ -77,7 +83,7 @@ void gridfs_destroy( gridfs *gfs ); ...@@ -77,7 +83,7 @@ void gridfs_destroy( gridfs *gfs );
* When done, you must call gridfs_writer_done to save the file metadata. * When done, you must call gridfs_writer_done to save the file metadata.
* *
*/ */
void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name, MONGO_EXPORT void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name,
const char *content_type ); const char *content_type );
/** /**
...@@ -86,7 +92,7 @@ void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name ...@@ -86,7 +92,7 @@ void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name
* stream to a GridFS file. When finished, be sure to call gridfs_writer_done. * stream to a GridFS file. When finished, be sure to call gridfs_writer_done.
* *
*/ */
void gridfile_write_buffer( gridfile *gfile, const char *data, MONGO_EXPORT void gridfile_write_buffer( gridfile *gfile, const char *data,
gridfs_offset length ); gridfs_offset length );
/** /**
...@@ -96,7 +102,7 @@ void gridfile_write_buffer( gridfile *gfile, const char *data, ...@@ -96,7 +102,7 @@ void gridfile_write_buffer( gridfile *gfile, const char *data,
* *
* @return - MONGO_OK or MONGO_ERROR. * @return - MONGO_OK or MONGO_ERROR.
*/ */
int gridfile_writer_done( gridfile *gfile ); MONGO_EXPORT int gridfile_writer_done( gridfile *gfile );
/** /**
* Store a buffer as a GridFS file. * Store a buffer as a GridFS file.
...@@ -108,7 +114,7 @@ int gridfile_writer_done( gridfile *gfile ); ...@@ -108,7 +114,7 @@ int gridfile_writer_done( gridfile *gfile );
* *
* @return - MONGO_OK or MONGO_ERROR. * @return - MONGO_OK or MONGO_ERROR.
*/ */
int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length, MONGO_EXPORT int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length,
const char *remotename, const char *remotename,
const char *contenttype ); const char *contenttype );
...@@ -121,7 +127,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length, ...@@ -121,7 +127,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length,
* *
* @return - MONGO_OK or MONGO_ERROR. * @return - MONGO_OK or MONGO_ERROR.
*/ */
int gridfs_store_file( gridfs *gfs, const char *filename, MONGO_EXPORT int gridfs_store_file( gridfs *gfs, const char *filename,
const char *remotename, const char *contenttype ); const char *remotename, const char *contenttype );
/** /**
...@@ -129,7 +135,7 @@ int gridfs_store_file( gridfs *gfs, const char *filename, ...@@ -129,7 +135,7 @@ int gridfs_store_file( gridfs *gfs, const char *filename,
* @param gfs - the working GridFS * @param gfs - the working GridFS
* @param filename - the filename of the file/s to be removed * @param filename - the filename of the file/s to be removed
*/ */
void gridfs_remove_filename( gridfs *gfs, const char *filename ); MONGO_EXPORT void gridfs_remove_filename( gridfs *gfs, const char *filename );
/** /**
* Find the first file matching the provided query within the * Find the first file matching the provided query within the
...@@ -141,7 +147,7 @@ void gridfs_remove_filename( gridfs *gfs, const char *filename ); ...@@ -141,7 +147,7 @@ void gridfs_remove_filename( gridfs *gfs, const char *filename );
* *
* @return MONGO_OK if successful, MONGO_ERROR otherwise * @return MONGO_OK if successful, MONGO_ERROR otherwise
*/ */
int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile ); MONGO_EXPORT int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile );
/** /**
* Find the first file referenced by filename within the GridFS * Find the first file referenced by filename within the GridFS
...@@ -152,7 +158,7 @@ int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile ); ...@@ -152,7 +158,7 @@ int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile );
* *
* @return MONGO_OK or MONGO_ERROR. * @return MONGO_OK or MONGO_ERROR.
*/ */
int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile ); MONGO_EXPORT int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile );
/** /**
* Initializes a GridFile containing the GridFS and file bson * Initializes a GridFile containing the GridFS and file bson
...@@ -162,20 +168,20 @@ int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile ); ...@@ -162,20 +168,20 @@ int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile );
* *
* @return - MONGO_OK or MONGO_ERROR. * @return - MONGO_OK or MONGO_ERROR.
*/ */
int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile ); MONGO_EXPORT int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile );
/** /**
* Destroys the GridFile * Destroys the GridFile
* *
* @param oGridFIle - the GridFile being destroyed * @param oGridFIle - the GridFile being destroyed
*/ */
void gridfile_destroy( gridfile *gfile ); MONGO_EXPORT void gridfile_destroy( gridfile *gfile );
/** /**
* Returns whether or not the GridFile exists * Returns whether or not the GridFile exists
* @param gfile - the GridFile being examined * @param gfile - the GridFile being examined
*/ */
bson_bool_t gridfile_exists( gridfile *gfile ); MONGO_EXPORT bson_bool_t gridfile_exists( gridfile *gfile );
/** /**
* Returns the filename of GridFile * Returns the filename of GridFile
...@@ -183,7 +189,7 @@ bson_bool_t gridfile_exists( gridfile *gfile ); ...@@ -183,7 +189,7 @@ bson_bool_t gridfile_exists( gridfile *gfile );
* *
* @return - the filename of the Gridfile * @return - the filename of the Gridfile
*/ */
const char *gridfile_get_filename( gridfile *gfile ); MONGO_EXPORT const char *gridfile_get_filename( gridfile *gfile );
/** /**
* Returns the size of the chunks of the GridFile * Returns the size of the chunks of the GridFile
...@@ -191,7 +197,7 @@ const char *gridfile_get_filename( gridfile *gfile ); ...@@ -191,7 +197,7 @@ const char *gridfile_get_filename( gridfile *gfile );
* *
* @return - the size of the chunks of the Gridfile * @return - the size of the chunks of the Gridfile
*/ */
int gridfile_get_chunksize( gridfile *gfile ); MONGO_EXPORT int gridfile_get_chunksize( gridfile *gfile );
/** /**
* Returns the length of GridFile's data * Returns the length of GridFile's data
...@@ -200,7 +206,7 @@ int gridfile_get_chunksize( gridfile *gfile ); ...@@ -200,7 +206,7 @@ int gridfile_get_chunksize( gridfile *gfile );
* *
* @return - the length of the Gridfile's data * @return - the length of the Gridfile's data
*/ */
gridfs_offset gridfile_get_contentlength( gridfile *gfile ); MONGO_EXPORT gridfs_offset gridfile_get_contentlength( gridfile *gfile );
/** /**
* Returns the MIME type of the GridFile * Returns the MIME type of the GridFile
...@@ -210,7 +216,7 @@ gridfs_offset gridfile_get_contentlength( gridfile *gfile ); ...@@ -210,7 +216,7 @@ gridfs_offset gridfile_get_contentlength( gridfile *gfile );
* @return - the MIME type of the Gridfile * @return - the MIME type of the Gridfile
* (NULL if no type specified) * (NULL if no type specified)
*/ */
const char *gridfile_get_contenttype( gridfile *gfile ); MONGO_EXPORT const char *gridfile_get_contenttype( gridfile *gfile );
/** /**
* Returns the upload date of GridFile * Returns the upload date of GridFile
...@@ -219,7 +225,7 @@ const char *gridfile_get_contenttype( gridfile *gfile ); ...@@ -219,7 +225,7 @@ const char *gridfile_get_contenttype( gridfile *gfile );
* *
* @return - the upload date of the Gridfile * @return - the upload date of the Gridfile
*/ */
bson_date_t gridfile_get_uploaddate( gridfile *gfile ); MONGO_EXPORT bson_date_t gridfile_get_uploaddate( gridfile *gfile );
/** /**
* Returns the MD5 of GridFile * Returns the MD5 of GridFile
...@@ -228,7 +234,7 @@ bson_date_t gridfile_get_uploaddate( gridfile *gfile ); ...@@ -228,7 +234,7 @@ bson_date_t gridfile_get_uploaddate( gridfile *gfile );
* *
* @return - the MD5 of the Gridfile * @return - the MD5 of the Gridfile
*/ */
const char *gridfile_get_md5( gridfile *gfile ); MONGO_EXPORT const char *gridfile_get_md5( gridfile *gfile );
/** /**
* Returns the field in GridFile specified by name * Returns the field in GridFile specified by name
...@@ -260,7 +266,7 @@ bson_bool_t gridfile_get_boolean( gridfile *gfile, ...@@ -260,7 +266,7 @@ bson_bool_t gridfile_get_boolean( gridfile *gfile,
* @return - the metadata of the Gridfile in a bson object * @return - the metadata of the Gridfile in a bson object
* (an empty bson is returned if none exists) * (an empty bson is returned if none exists)
*/ */
bson gridfile_get_metadata( gridfile *gfile ); MONGO_EXPORT void gridfile_get_metadata( gridfile *gfile, bson* out );
/** /**
* Returns the number of chunks in the GridFile * Returns the number of chunks in the GridFile
...@@ -268,7 +274,7 @@ bson gridfile_get_metadata( gridfile *gfile ); ...@@ -268,7 +274,7 @@ bson gridfile_get_metadata( gridfile *gfile );
* *
* @return - the number of chunks in the Gridfile * @return - the number of chunks in the Gridfile
*/ */
int gridfile_get_numchunks( gridfile *gfile ); MONGO_EXPORT int gridfile_get_numchunks( gridfile *gfile );
/** /**
* Returns chunk n of GridFile * Returns chunk n of GridFile
...@@ -276,7 +282,7 @@ int gridfile_get_numchunks( gridfile *gfile ); ...@@ -276,7 +282,7 @@ int gridfile_get_numchunks( gridfile *gfile );
* *
* @return - the nth chunk of the Gridfile * @return - the nth chunk of the Gridfile
*/ */
bson gridfile_get_chunk( gridfile *gfile, int n ); MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out );
/** /**
* Returns a mongo_cursor of *size* chunks starting with chunk *start* * Returns a mongo_cursor of *size* chunks starting with chunk *start*
...@@ -287,7 +293,7 @@ bson gridfile_get_chunk( gridfile *gfile, int n ); ...@@ -287,7 +293,7 @@ bson gridfile_get_chunk( gridfile *gfile, int n );
* *
* @return - mongo_cursor of the chunks (must be destroyed after use) * @return - mongo_cursor of the chunks (must be destroyed after use)
*/ */
mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ); MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size );
/** /**
* Writes the GridFile to a stream * Writes the GridFile to a stream
...@@ -295,7 +301,7 @@ mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ); ...@@ -295,7 +301,7 @@ mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size );
* @param gfile - the working GridFile * @param gfile - the working GridFile
* @param stream - the file stream to write to * @param stream - the file stream to write to
*/ */
gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ); MONGO_EXPORT gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream );
/** /**
* Reads length bytes from the GridFile to a buffer * Reads length bytes from the GridFile to a buffer
...@@ -309,7 +315,7 @@ gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ); ...@@ -309,7 +315,7 @@ gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream );
* *
* @return - the number of bytes read * @return - the number of bytes read
*/ */
gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ); MONGO_EXPORT gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf );
/** /**
* Updates the position in the file * Updates the position in the file
...@@ -321,6 +327,6 @@ gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ); ...@@ -321,6 +327,6 @@ gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf );
* *
* @return - resulting offset location * @return - resulting offset location
*/ */
gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ); MONGO_EXPORT gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset );
#endif #endif
...@@ -309,7 +309,7 @@ mongo_md5_process(mongo_md5_state_t *pms, const mongo_md5_byte_t *data /*[64]*/) ...@@ -309,7 +309,7 @@ mongo_md5_process(mongo_md5_state_t *pms, const mongo_md5_byte_t *data /*[64]*/)
pms->abcd[3] += d; pms->abcd[3] += d;
} }
void MONGO_EXPORT void
mongo_md5_init(mongo_md5_state_t *pms) mongo_md5_init(mongo_md5_state_t *pms)
{ {
pms->count[0] = pms->count[1] = 0; pms->count[0] = pms->count[1] = 0;
...@@ -319,7 +319,7 @@ mongo_md5_init(mongo_md5_state_t *pms) ...@@ -319,7 +319,7 @@ mongo_md5_init(mongo_md5_state_t *pms)
pms->abcd[3] = 0x10325476; pms->abcd[3] = 0x10325476;
} }
void MONGO_EXPORT void
mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes) mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes)
{ {
const mongo_md5_byte_t *p = data; const mongo_md5_byte_t *p = data;
...@@ -357,7 +357,7 @@ mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbyte ...@@ -357,7 +357,7 @@ mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbyte
memcpy(pms->buf, p, left); memcpy(pms->buf, p, left);
} }
void MONGO_EXPORT void
mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]) mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16])
{ {
static const mongo_md5_byte_t pad[64] = { static const mongo_md5_byte_t pad[64] = {
......
...@@ -47,8 +47,8 @@ ...@@ -47,8 +47,8 @@
1999-05-03 lpd Original version. 1999-05-03 lpd Original version.
*/ */
#ifndef md5_INCLUDED #ifndef MONGO_MD5_H_
# define md5_INCLUDED #define MONGO_MD5_H_
/* /*
* This package supports both compile-time and run-time determination of CPU * This package supports both compile-time and run-time determination of CPU
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
* run on either big- or little-endian CPUs, but will run slightly less * run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/ */
#include "bson.h"
typedef unsigned char mongo_md5_byte_t; /* 8-bit byte */ typedef unsigned char mongo_md5_byte_t; /* 8-bit byte */
typedef unsigned int mongo_md5_word_t; /* 32-bit word */ typedef unsigned int mongo_md5_word_t; /* 32-bit word */
...@@ -75,17 +76,17 @@ extern "C" ...@@ -75,17 +76,17 @@ extern "C"
{ {
#endif #endif
/* Initialize the algorithm. */ /* Initialize the algorithm. */
void mongo_md5_init(mongo_md5_state_t *pms); MONGO_EXPORT void mongo_md5_init(mongo_md5_state_t *pms);
/* Append a string to the message. */ /* Append a string to the message. */
void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes); MONGO_EXPORT void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes);
/* Finish the message and return the digest. */ /* Finish the message and return the digest. */
void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]); MONGO_EXPORT void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]);
#ifdef __cplusplus #ifdef __cplusplus
} /* end extern "C" */ } /* end extern "C" */
#endif #endif
#endif /* md5_INCLUDED */ #endif /* MONGO_MD5_H_ */
/* Copyright 2009-2011 10gen Inc. /* Copyright 2009-2012 10gen Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
......
/** @file platform.h */
/** Copyright 2009-2011 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* all platform-specific ifdefs should go here */
#ifndef _PLATFORM_HACKS_H_
#define _PLATFORM_HACKS_H_
#ifdef __GNUC__
#define MONGO_INLINE static __inline__
#else
#define MONGO_INLINE static
#endif
#ifdef __cplusplus
#define MONGO_EXTERN_C_START extern "C" {
#define MONGO_EXTERN_C_END }
#else
#define MONGO_EXTERN_C_START
#define MONGO_EXTERN_C_END
#endif
#if defined(MONGO_HAVE_STDINT) || __STDC_VERSION__ >= 199901L
#include <stdint.h>
#elif defined(MONGO_HAVE_UNISTD)
#include <unistd.h>
#elif defined(MONGO_USE__INT64)
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#elif defined(MONGO_USE_LONG_LONG_INT)
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
#else
#error must have a 64bit int type
#endif
/* big endian is only used for OID generation. little is used everywhere else */
#ifdef MONGO_BIG_ENDIAN
#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) )
#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) )
#define bson_big_endian64(out, in) ( memcpy(out, in, 8) )
#define bson_big_endian32(out, in) ( memcpy(out, in, 4) )
#else
#define bson_little_endian64(out, in) ( memcpy(out, in, 8) )
#define bson_little_endian32(out, in) ( memcpy(out, in, 4) )
#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) )
#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) )
#endif
MONGO_EXTERN_C_START
MONGO_INLINE void bson_swap_endian64( void *outp, const void *inp ) {
const char *in = ( const char * )inp;
char *out = ( char * )outp;
out[0] = in[7];
out[1] = in[6];
out[2] = in[5];
out[3] = in[4];
out[4] = in[3];
out[5] = in[2];
out[6] = in[1];
out[7] = in[0];
}
MONGO_INLINE void bson_swap_endian32( void *outp, const void *inp ) {
const char *in = ( const char * )inp;
char *out = ( char * )outp;
out[0] = in[3];
out[1] = in[2];
out[2] = in[1];
out[3] = in[0];
}
MONGO_EXTERN_C_END
#endif
/**
* @file net.h
* @brief Networking.
*/
/* Copyright 2009-2011 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Header for Linux net.h */
#ifndef _MONGO_NET_H_
#define _MONGO_NET_H_
#include "mongo.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#define mongo_close_socket(sock) ( close(sock) )
#if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1
#define _MONGO_USE_GETADDRINFO
#endif
MONGO_EXTERN_C_START
int mongo_set_socket_op_timeout( mongo *conn, int millis );
int mongo_read_socket( mongo *conn, void *buf, int len );
int mongo_write_socket( mongo *conn, const void *buf, int len );
int mongo_socket_connect( mongo *conn, const char *host, int port );
MONGO_EXTERN_C_END
#endif
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论