Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
* [Scott McWhirter](https://github.com/konobi)
* Facilities to do in-memory db lookups, mmap and file update checks
* [Theo Schlossnagle](https://github.com/postwait)
* Update to use 0.8.0 APIs
33 changes: 33 additions & 0 deletions binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
'conditions': [
['OS=="solaris"', {
'targets': [
{
'target_name': 'ceoip',
'sources': [ 'src/ceoip.cc' ],
'libraries': [ '-lGeoIP', '-liconv' ],
'conditions': [
['target_arch=="ia32"', {
'cflags': [ '-fpermissive', '-I/opt/omni/include' ],
'ldflags': [ '-L/opt/omni/lib -R/opt/omni/lib' ]
}],
['target_arch=="x64"', {
'cflags': [ '-fpermissive', '-I/opt/omni/include/amd64' ],
'ldflags': [ '-L/opt/omni/lib/amd64 -R/opt/omni/lib/amd64' ]
}]
]
}
]
}],
['OS!="solaris"', {
'targets': [
{
'target_name': 'ceoip',
'sources': [ 'src/ceoip.cc' ],
'libraries': [ '-lGeoIP' ],
'cflags': [ '-I/opt/omni/include' ],
}
]
}]
]
}
17 changes: 17 additions & 0 deletions lib/ceoip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2012 Circonus, Inc. All rights reserved.

var ceoip = require('../build/Release/ceoip');
var events = require('events');

inherits(ceoip.Connection, events.EventEmitter);
exports.Connection = ceoip.Connection;
exports.GEOIP_STANDARD = ceoip.GEOIP_STANDARD;
exports.GEOIP_MEMORY_CACHE = ceoip.GEOIP_MEMORY_CACHE;
exports.GEOIP_CHECK_CACHE = ceoip.GEOIP_CHECK_CACHE;
exports.GEOIP_INDEX_CACHE = ceoip.GEOIP_INDEX_CACHE;
exports.GEOIP_MMAP_CACHE = ceoip.GEOIP_MMAP_CACHE;

function inherits(target, source) {
for (var k in source.prototype)
target.prototype[k] = source.prototype[k];
}
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"author": "strange (https://github.com/strange)",
"name": "geoip",
"description": "Geoip for node",
"version": "0.2.0",
"repository": {
"type": "git",
"url": "git://github.com/postwait/node-geoip.git"
},
"main": "./lib/geoip",
"engines": {
"node": ">0.10.0"
},
"script":{"install": "npm install"},
"dependencies": {},
"devDependencies": {}
}
67 changes: 46 additions & 21 deletions src/ceoip.cc
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright 2010 Gustaf Sjöberg <[email protected]>
// Copyright 2012 Circonus, Inc. All rights reserved.
#include <GeoIP.h>
#include <GeoIPCity.h>

#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <assert.h>
#include <iconv.h>

using namespace v8;
using namespace node;
Expand All @@ -14,15 +15,17 @@ static Persistent<String> connected_symbol;
static Persistent<String> closed_symbol;
static Persistent<String> error_symbol;
static Persistent<String> result_symbol;
static iconv_t cd;

class Connection : public EventEmitter {
class Connection : ObjectWrap {
public:
static void
Initialize(v8::Handle<v8::Object> target) {
Local<FunctionTemplate> t = FunctionTemplate::New(Connection::New);
t->Inherit(EventEmitter::constructor_template);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(String::New("ceoip.Connection"));

cd = iconv_open("utf-8", "ISO-8859-1");
closed_symbol = NODE_PSYMBOL("closed");
connected_symbol = NODE_PSYMBOL("connected");
error_symbol = NODE_PSYMBOL("error");
Expand All @@ -41,29 +44,30 @@ class Connection : public EventEmitter {
target->Set(String::NewSymbol("Connection"), t->GetFunction());
}

void Connect(const char *dbpath, int db_opts_bitmask) {
void Connect(const Arguments &args, const char *dbpath, int db_opts_bitmask) {
HandleScope scope;

if(db_opts_bitmask == 0){
db_opts_bitmask = 0 | GEOIP_STANDARD;
}
gi = GeoIP_open(dbpath, db_opts_bitmask);

Emit((gi ? connected_symbol : error_symbol), 0, NULL);
Handle<Value> argv[1] = { gi ? connected_symbol : error_symbol };
MakeCallback(args.This(), "emit", 1, argv);
}

void Close() {
void CloseHandle(const Arguments &args) {
HandleScope scope;

if (gi != NULL) {
GeoIP_delete(gi);
gi = NULL;
}

Emit(closed_symbol, 0, NULL);
Handle<Value> argv[1] = { closed_symbol };
MakeCallback(args.This(), "emit", 1, argv);
}

void Query(const char *query) {
void Query(const Arguments &args, const char *query) {
HandleScope scope;

assert(gi);
Expand All @@ -73,9 +77,11 @@ class Connection : public EventEmitter {
if (record) {
Local<Value> result = BuildResult(record);
GeoIPRecord_delete(record);
Emit(result_symbol, 1, &result);
Handle<Value> argv[2] = { result_symbol, result };
MakeCallback(args.This(), "emit", 2, argv);
} else {
Emit(result_symbol, 0, NULL);
Handle<Value> argv[1] = { result_symbol };
MakeCallback(args.This(), "emit", 1, argv);
}
}

Expand Down Expand Up @@ -107,7 +113,7 @@ class Connection : public EventEmitter {


Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
connection->Connect(*dbpath, args[1]->ToUint32()->Value());
connection->Connect(args, *dbpath, args[1]->ToUint32()->Value());

return Undefined();
}
Expand All @@ -116,7 +122,7 @@ class Connection : public EventEmitter {
HandleScope scope;

Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
connection->Close();
connection->CloseHandle(args);

return Undefined();
}
Expand All @@ -133,24 +139,38 @@ class Connection : public EventEmitter {
String::Utf8Value query(args[0]->ToString());

Connection *connection = ObjectWrap::Unwrap<Connection>(args.This());
connection->Query(*query);
connection->Query(args, *query);

return Undefined();
}

private:

#ifndef ICONV_SRC_CONST
#define ICONV_SRC_CONST
#endif
#define icv(a,b,blen) do { \
ICONV_SRC_CONST char *in = a; \
char *out = b; \
size_t inlen = strlen(a); \
size_t outlen = blen; \
if(iconv(cd, &in, &inlen, &out, &outlen) == -1) b[0] = '\0'; \
else *out = '\0'; \
} while(0)

Local<Value>BuildResult(GeoIPRecord *record) {
HandleScope scope;
char outputbuff[1024];

Local<Array> result = Array::New();

if (record->longitude != NULL) {
if (record->longitude != (int)NULL) {
result->Set(
String::New("longitude"),
Number::New(record->longitude)
);
}
if (record->latitude != NULL) {
if (record->latitude != (int)NULL) {
result->Set(
String::New("latitude"),
Number::New(record->latitude)
Expand All @@ -168,34 +188,37 @@ class Connection : public EventEmitter {
String::New(record->continent_code)
);
}
if (record->metro_code != NULL) {
if (record->metro_code != (int)NULL) {
result->Set(
String::New("metro_code"),
Number::New(record->metro_code)
);
}
if (record->country_name != NULL) {
icv(record->country_name, outputbuff, sizeof(outputbuff));
result->Set(
String::New("country"),
String::New(record->country_name)
String::New(outputbuff)
);
}
if (record->city != NULL) {
icv(record->city, outputbuff, sizeof(outputbuff));
result->Set(
String::New("city"),
String::New(record->city)
String::New(outputbuff)
);
}
if (record->area_code != NULL) {
if (record->area_code != (int)NULL) {
result->Set(
String::New("area_code"),
Number::New(record->area_code)
);
}
if (record->region != NULL) {
icv(record->region, outputbuff, sizeof(outputbuff));
result->Set(
String::New("region"),
String::New(record->region)
String::New(outputbuff)
);
}

Expand All @@ -210,3 +233,5 @@ init(Handle<Object> target) {
HandleScope scope;
Connection::Initialize(target);
}

NODE_MODULE(ceoip, init)
3 changes: 3 additions & 0 deletions wscript
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import sys

srcdir = os.path.abspath('.')
blddir = 'build'
Expand All @@ -12,6 +13,8 @@ def configure(conf):
conf.check_tool('compiler_cxx')
conf.check_tool('node_addon')
conf.check_cxx(lib='GeoIP', mandatory=True, uselib_store='GeoIP')
if not sys.platform.startswith("linux"):
conf.check_cxx(lib='iconv', mandatory=True, uselib_store='GeoIP')

def build(context, target=target):
obj = context.new_task_gen('cxx', 'shlib', 'node_addon')
Expand Down