提交 a9169199 authored 作者: Daniel Swarbrick's avatar Daniel Swarbrick

add MongoDB CDR module

上级 aff4bcbe
include ../../../../build/modmake.rules
MONGODB_DRIVER=./driver/src
LOCAL_CFLAGS=-I$(MONGODB_DRIVER)
LOCAL_OBJS=$(MONGODB_DRIVER)/md5.o \
$(MONGODB_DRIVER)/mongo.o $(MONGODB_DRIVER)/net.o \
$(MONGODB_DRIVER)/bson.o $(MONGODB_DRIVER)/numbers.o $(MONGODB_DRIVER)/encoding.o \
local_depend: $(LOCAL_OBJS)
# MongoDB C Driver History
## 0.4
THIS RELEASE INCLUDES NUMEROUS BACKWARD-BREAKING CHANGES.
These changes have been made for extensibility, consistency,
and ease of use. Please read the following release notes
carefully, and study the updated tutorial.
API Principles:
1. Present a consistent interface for all objects: connections,
cursors, bson objects, and bson iterators.
2. Require no knowledge of an object's implementation to use the API.
3. Allow users to allocate objects on the stack or on the heap.
4. Integrate API with new error reporting strategy.
5. Be concise, except where it impairs clarity.
Changes:
* mongo_replset_init_conn has been renamed to mongo_replset_init.
* bson_buffer has been removed. All functions for building bson
objects now take objects of type bson. The new pattern looks like this:
Example:
bson b[1];
bson_init( b );
bson_append_int( b, "foo", 1 );
bson_finish( b );
/* The object is ready to use.
When finished, destroy it. */
bson_destroy( b );
* mongo_connection has been renamed to mongo.
Example:
mongo conn[1];
mongo_connect( conn, '127.0.0.1', 27017 );
/* Connection is ready. Destroy when down. */
mongo_destroy( conn );
* New cursor builder API for clearer code:
Example:
mongo_cursor cursor[1];
mongo_cursor_init( cursor, conn, "test.foo" );
bson query[1];
bson_init( query );
bson_append_int( query, "bar", 1 );
bson_finish( query );
bson fields[1];
bson_init( fields );
bson_append_int( fields, "baz", 1 );
bson_finish( fields );
mongo_cursor_set_query( cursor, query );
mongo_cursor_set_fields( cursor, fields );
mongo_cursor_set_limit( cursor, 10 );
mongo_cursor_set_skip( cursor, 10 );
while( mongo_cursor_next( cursor ) == MONGO_OK )
bson_print( mongo_cursor_bson( cursor ) );
* bson_iterator_init now takes a (bson*) instead of a (const char*). This is consistent
with bson_find, which also takes a (bson*). If you want to initiate a bson iterator
with a buffer, use the new function bson_iterator_from_buffer.
* With the addition of the mongo_cursor_bson function, it's now no
longer necessary to know how bson and mongo_cursor objects are implemented.
Example:
bson b[1];
bson_iterator i[1];
bson_iterator_init( i, b );
/* With a cursor */
bson_iterator_init( i, mongo_cursor_bson( cursor ) );
* Added mongo_cursor_data and bson_data functions, which return the
raw bson buffer as a (const char *).
* All constants that were once lower case are now
upper case. These include: MONGO_OP_MSG, MONGO_OP_UPDATE, MONGO_OP_INSERT,
MONGO_OP_QUERY, MONGO_OP_GET_MORE, MONGO_OP_DELETE, MONGO_OP_KILL_CURSORS
BSON_EOO, BSON_DOUBLE, BSON_STRING, BSON_OBJECT, BSON_ARRAY, BSON_BINDATA,
BSON_UNDEFINED, BSON_OID, BSON_BOOL, BSON_DATE, BSON_NULL, BSON_REGEX, BSON_DBREF,
BSON_CODE, BSON_SYMBOL, BSON_CODEWSCOPE, BSON_INT, BSON_TIMESTAMP, BSON_LONG,
MONGO_CONN_SUCCESS, MONGO_CONN_BAD_ARG, MONGO_CONN_NO_SOCKET, MONGO_CONN_FAIL,
MONGO_CONN_NOT_MASTER, MONGO_CONN_BAD_SET_NAME, MONGO_CONN_CANNOT_FIND_PRIMARY
If your programs use any of these constants, you must convert them to their
upper case forms, or you will see compile errors.
* The error handling strategy has been changed. Exceptions are not longer being used.
* Functions taking a mongo_connection object now return either MONGO_OK or MONGO_ERROR.
In case of an error, an error code of type mongo_error_t will be indicated on the
mongo_connection->err field.
* Functions taking a bson object now return either BSON_OK or BSON_ERROR.
In case of an error, an error code of type bson_validity_t will be indicated on the
bson->err or bson_buffer->err field.
* Calls to mongo_cmd_get_last_error store the error status on the
mongo->lasterrcode and mongo->lasterrstr fields.
* bson_print now prints all types.
* Users may now set custom malloc, realloc, free, printf, sprintf, and fprintf fields.
* Groundwork for modules for supporting platform-specific features (e.g., socket timeouts).
* Added mongo_set_op_timeout for setting socket timeout. To take advantage of this, you must
compile with --use-platform=LINUX. The compiles with platform/linux/net.h instead of the
top-level net.h.
* Fixed tailable cursors.
* GridFS API is now in-line with the new driver API. In particular, all of the
following functions now return MONGO_OK or MONGO_ERROR: gridfs_init,
gridfile_init, gridfile_writer_done, gridfs_store_buffer, gridfs_store_file,
and gridfs_find_query.
* Fixed a few memory leaks.
## 0.3
2011-4-14
* Support replica sets.
* Better standard connection API.
* GridFS write buffers iteratively.
* Fixes for working with large GridFS files (> 3GB)
* bson_append_string_n and family (Gergely Nagy)
## 0.2
2011-2-11
* GridFS support (Chris Triolo).
* BSON Timestamp type support.
## 0.1
2009-11-30
* Initial release.
# MongoDB C Driver
This is then 10gen-supported MongoDB C driver. There are two goals for this driver.
The first is to provide a strict, default compilation option for ultimate portability,
no dependencies, and generic embeddability.
The second is to support more advanced, platform-specific features, like socket timeout,
by providing an interface for platform-specific modules.
Until the 1.0 release, this driver should be considered alpha. Keep in mind that the API will be in flux until then.
# Building
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:
git checkout v0.4
You can then build the driver with scons:
scons
## Running the tests
Make sure that you're running mongod on 127.0.0.1 on the default port (27017). The replica set
test assumes a replica set with at least three nodes running at 127.0.0.1 and starting at port
30000. Note that the driver does not recognize 'localhost' as a valid host name.
To compile and run the tests:
scons test
# Error Handling
Most functions return MONGO_OK or BSON_OK on success and MONGO_ERROR or BSON_ERROR on failure.
Specific error codes and error strings are then stored in the `err` and `errstr` fields of the
`mongo` and `bson` objects. It is the client's responsibility to check for errors and handle
them appropriately.
# Docs
The docs are built using Sphinx and Doxygen. If you have these tools installed, then
you can build the docs with scons:
scons docs
The html docs will appear in docs/html.
# ISSUES
You can report bugs, request new features, and view this driver's roadmap
using [JIRA](http://jira.mongodb.org/browse/CDRIVER).
# CREDITS
* Gergely Nagy - Non-null-terminated string support.
* Josh Rotenberg - Initial Doxygen setup and a significant chunk of documentation.
# LICENSE
Unless otherwise specified in a source file, sources in this
repository are published under the terms of the Apache License version
2.0, a copy of which is in this repository as APACHE-2.0.txt.
# -*- 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.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Portions Copyright 2001 Unicode, Inc.
*
* Disclaimer
*
* This source code is provided as is by Unicode, Inc. No claims are
* made as to fitness for any particular purpose. No warranties of any
* kind are expressed or implied. The recipient agrees to determine
* applicability of information provided. If this file has been
* purchased on magnetic or optical media from Unicode, Inc., the
* sole remedy for any claim will be exchange of defective media
* within 90 days of receipt.
*
* Limitations on Rights to Redistribute This Code
*
* Unicode, Inc. hereby grants the right to freely use the information
* supplied in this file in the creation of products supporting the
* Unicode Standard, and to make copies of this file in any form
* for internal or external distribution as long as this notice
* remains attached.
*/
#include "bson.h"
#include "encoding.h"
/*
* Index into the table below with the first byte of a UTF-8 sequence to
* get the number of trailing bytes that are supposed to follow it.
*/
static const char trailingBytesForUTF8[256] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
};
/* --------------------------------------------------------------------- */
/*
* Utility routine to tell whether a sequence of bytes is legal UTF-8.
* This must be called with the length pre-determined by the first byte.
* The length can be set by:
* length = trailingBytesForUTF8[*source]+1;
* and the sequence is illegal right away if there aren't that many bytes
* available.
* If presented with a length > 4, this returns 0. The Unicode
* definition of UTF-8 goes up to 4-byte sequences.
*/
static int isLegalUTF8( const unsigned char *source, int length ) {
unsigned char a;
const unsigned char *srcptr = source + length;
switch ( length ) {
default:
return 0;
/* Everything else falls through when "true"... */
case 4:
if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0;
case 3:
if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0;
case 2:
if ( ( a = ( *--srcptr ) ) > 0xBF ) return 0;
switch ( *source ) {
/* no fall-through in this inner switch */
case 0xE0:
if ( a < 0xA0 ) return 0;
break;
case 0xF0:
if ( a < 0x90 ) return 0;
break;
case 0xF4:
if ( a > 0x8F ) return 0;
break;
default:
if ( a < 0x80 ) return 0;
}
case 1:
if ( *source >= 0x80 && *source < 0xC2 ) return 0;
if ( *source > 0xF4 ) return 0;
}
return 1;
}
static int bson_validate_string( bson *b, const unsigned char *string,
const int length, const char check_utf8, const char check_dot,
const char check_dollar ) {
int position = 0;
int sequence_length = 1;
if( check_dollar && string[0] == '$' ) {
b->err |= BSON_FIELD_INIT_DOLLAR;
}
while ( position < length ) {
if ( check_dot && *( string + position ) == '.' ) {
b->err |= BSON_FIELD_HAS_DOT;
}
if ( check_utf8 ) {
sequence_length = trailingBytesForUTF8[*( string + position )] + 1;
if ( ( position + sequence_length ) > length ) {
b->err |= BSON_NOT_UTF8;
return BSON_ERROR;
}
if ( !isLegalUTF8( string + position, sequence_length ) ) {
b->err |= BSON_NOT_UTF8;
return BSON_ERROR;
}
}
position += sequence_length;
}
return BSON_OK;
}
int bson_check_string( bson *b, const char *string,
const int length ) {
return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 );
}
int bson_check_field_name( bson *b, const char *string,
const int length ) {
return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 );
}
/*
* 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.
*/
#ifndef _BSON_ENCODING_H_
#define _BSON_ENCODING_H_
MONGO_EXTERN_C_START
/**
* Check that a field name is valid UTF8, does not start with a '$',
* and contains no '.' characters. Set bson bit field appropriately.
* Note that we don't need to check for '\0' because we're using
* strlen(3), which stops at '\0'.
*
* @param b The bson object to which field name will be appended.
* @param string The field name as char*.
* @param length The length of the field name.
*
* @return BSON_OK if valid UTF8 and BSON_ERROR if not. All BSON strings must be
* valid UTF8. This function will also check whether the string
* contains '.' or starts with '$', since the validity of this depends on context.
* Set the value of b->err appropriately.
*/
int bson_check_field_name( bson *b, const char *string,
const int length );
/**
* Check that a string is valid UTF8. Sets the buffer bit field appropriately.
*
* @param b The bson object to which string will be appended.
* @param string The string to check.
* @param length The length of the string.
*
* @return BSON_OK if valid UTF-8; otherwise, BSON_ERROR.
* Sets b->err on error.
*/
bson_bool_t bson_check_string( bson *b, const char *string,
const int length );
MONGO_EXTERN_C_END
#endif
/*
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
<ghost@aladdin.com>. 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 <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef md5_INCLUDED
# define md5_INCLUDED
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* 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.
*/
typedef unsigned char mongo_md5_byte_t; /* 8-bit byte */
typedef unsigned int mongo_md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct mongo_md5_state_s {
mongo_md5_word_t count[2]; /* message length in bits, lsw first */
mongo_md5_word_t abcd[4]; /* digest buffer */
mongo_md5_byte_t buf[64]; /* accumulate block */
} mongo_md5_state_t;
#ifdef __cplusplus
extern "C"
{
#endif
/* Initialize the algorithm. */
void mongo_md5_init(mongo_md5_state_t *pms);
/* Append a string to the message. */
void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes);
/* Finish the message and return the digest. */
void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* md5_INCLUDED */
/* net.c */
/* 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.
*/
/* Implementation for generic version of net.h */
#include "net.h"
#include <string.h>
int mongo_write_socket( mongo *conn, const void *buf, int len ) {
const char *cbuf = buf;
while ( len ) {
int sent = send( conn->sock, cbuf, len, 0 );
if ( sent == -1 ) {
conn->err = MONGO_IO_ERROR;
return MONGO_ERROR;
}
cbuf += sent;
len -= sent;
}
return MONGO_OK;
}
int mongo_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 ) {
conn->err = MONGO_IO_ERROR;
return MONGO_ERROR;
}
cbuf += sent;
len -= sent;
}
return MONGO_OK;
}
/* This is a no-op in the generic implementation. */
int mongo_set_socket_op_timeout( mongo *conn, int millis ) {
return MONGO_OK;
}
static int mongo_create_socket( mongo *conn ) {
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;
socklen_t addressSize;
int flag = 1;
if( mongo_create_socket( conn ) != MONGO_OK )
return MONGO_ERROR;
memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) );
sa.sin_family = AF_INET;
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 ) {
mongo_close_socket( conn->sock );
conn->connected = 0;
conn->sock = 0;
conn->err = MONGO_CONN_FAIL;
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;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论