[geos-commits] r3631 - in trunk: . capi include/geos/util src/util
tests/unit tests/unit/capi
svn_geos at osgeo.org
svn_geos at osgeo.org
Wed May 16 08:20:42 EDT 2012
Author: strk
Date: 2012-05-16 05:20:42 -0700 (Wed, 16 May 2012)
New Revision: 3631
Added:
trunk/include/geos/util/CustomAllocators.h
trunk/src/util/CustomAllocators.cpp
trunk/tests/unit/capi/GEOSCustomAllocatorTest.cpp
Modified:
trunk/NEWS
trunk/capi/geos_c.cpp
trunk/capi/geos_c.h.in
trunk/capi/geos_ts_c.cpp
trunk/include/geos/util/Makefile.am
trunk/src/util/Makefile.am
trunk/tests/unit/Makefile.am
Log:
Allow passing custom memory managment functions (#540)
This is both in the C++ library _and_ the C library.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2012-05-16 10:29:01 UTC (rev 3630)
+++ trunk/NEWS 2012-05-16 12:20:42 UTC (rev 3631)
@@ -4,6 +4,7 @@
- New things:
- CAPI: GEOSNode (#496) - PHP: Geometry->node
- GeometryPrecisionReducer class
+ - Allow passing custom memory managment functions (#540)
- C++ API changes:
- New noding::GeometryNoder class
- Added BufferOp::setSingleSided
Modified: trunk/capi/geos_c.cpp
===================================================================
--- trunk/capi/geos_c.cpp 2012-05-16 10:29:01 UTC (rev 3630)
+++ trunk/capi/geos_c.cpp 2012-05-16 12:20:42 UTC (rev 3631)
@@ -26,6 +26,9 @@
#include <geos/operation/union/CascadedPolygonUnion.h>
#include <geos/algorithm/distance/DiscreteHausdorffDistance.h>
+#include <stdexcept>
+#include <new>
+
#ifdef _MSC_VER
#pragma warning(disable : 4099)
#endif
@@ -114,7 +117,7 @@
{
GEOSFree_r( handle, buffer );
}
-
+
/****************************************************************
** relate()-related functions
** return 0 = false, 1 = true, 2 = error occured
Modified: trunk/capi/geos_c.h.in
===================================================================
--- trunk/capi/geos_c.h.in 2012-05-16 10:29:01 UTC (rev 3630)
+++ trunk/capi/geos_c.h.in 2012-05-16 12:20:42 UTC (rev 3631)
@@ -137,6 +137,9 @@
typedef void (*GEOSQueryCallback)(void *item, void *userdata);
+typedef void * (*GEOSAllocator) (size_t size);
+typedef void (*GEOSFreer) (void *ptr);
+
/************************************************************************
*
* Initialization, cleanup, version
@@ -148,7 +151,10 @@
extern void GEOS_DLL initGEOS(GEOSMessageHandler notice_function,
GEOSMessageHandler error_function);
extern void GEOS_DLL finishGEOS(void);
+extern GEOSAllocator GEOS_DLL GEOS_setAllocator(GEOSAllocator nf);
+extern GEOSFreer GEOS_DLL GEOS_setFreer(GEOSFreer nf);
+
extern GEOSContextHandle_t GEOS_DLL initGEOS_r(
GEOSMessageHandler notice_function,
GEOSMessageHandler error_function);
Modified: trunk/capi/geos_ts_c.cpp
===================================================================
--- trunk/capi/geos_ts_c.cpp 2012-05-16 10:29:01 UTC (rev 3630)
+++ trunk/capi/geos_ts_c.cpp 2012-05-16 12:20:42 UTC (rev 3631)
@@ -58,6 +58,7 @@
#include <geos/operation/relate/RelateOp.h>
#include <geos/operation/sharedpaths/SharedPathsOp.h>
#include <geos/linearref/LengthIndexedLine.h>
+#include <geos/util/CustomAllocators.h>
#include <geos/util/IllegalArgumentException.h>
#include <geos/util/UniqueCoordinateArrayFilter.h>
#include <geos/util/Machine.h>
@@ -156,11 +157,54 @@
extern "C" const char GEOS_DLL *GEOSjtsport();
extern "C" char GEOS_DLL *GEOSasText(Geometry *g1);
+// --- Custom memory allocators -------------------------------- {
+
+GEOSAllocator geos_alloc = std::malloc;
+GEOSFreer geos_free = std::free;
+
+GEOSAllocator
+GEOS_setAllocator(GEOSAllocator nf)
+{
+ GEOSAllocator of = geos_alloc;
+ geos_alloc = nf;
+ geos::util::CustomAllocators::setAllocator(geos_alloc);
+ return of;
+}
+
+GEOSFreer
+GEOS_setFreer(GEOSFreer nf)
+{
+ GEOSFreer of = geos_free;
+ geos_free = nf;
+ geos::util::CustomAllocators::setFreer(geos_free);
+ return of;
+}
+
+void*
+operator new (std::size_t size, const std::nothrow_t&) throw () {
+ //cout << "new(" << size << ") called" << endl;
+ return geos_alloc(size);
+}
+
+void operator delete (void *ptr) throw () {
+ //cout << "delete(" << ptr << ") called" << endl;
+ if ( ptr ) geos_free(ptr);
+}
+
+void* operator new (std::size_t size) throw (std::bad_alloc) {
+ if ( void* ret = operator new (size, std::nothrow) ) return ret;
+ throw std::bad_alloc();
+}
+
+// ---------------------------------------------------------------- }
+
+
+
namespace { // anonymous
char* gstrdup_s(const char* str, const std::size_t size)
{
- char* out = static_cast<char*>(std::malloc(size + 1));
+ char* out = static_cast<char*>(geos_alloc(size + 1));
if (0 != out)
{
// as no strlen call necessary, memcpy may be faster than strcpy
@@ -193,7 +237,7 @@
GEOSContextHandleInternal_t *handle = 0;
void *extHandle = 0;
- extHandle = std::malloc(sizeof(GEOSContextHandleInternal_t));
+ extHandle = geos_alloc(sizeof(GEOSContextHandleInternal_t));
if (0 != extHandle)
{
handle = static_cast<GEOSContextHandleInternal_t*>(extHandle);
@@ -246,7 +290,7 @@
finishGEOS_r(GEOSContextHandle_t extHandle)
{
// Fix up freeing handle w.r.t. malloc above
- std::free(extHandle);
+ geos_free(extHandle);
extHandle = NULL;
}
@@ -255,7 +299,7 @@
{
assert(0 != extHandle);
- std::free(buffer);
+ geos_free(buffer);
}
//-----------------------------------------------------------
@@ -1240,7 +1284,7 @@
const std::size_t len = wkbstring.length();
unsigned char* result = 0;
- result = static_cast<unsigned char*>(std::malloc(len));
+ result = static_cast<unsigned char*>(geos_alloc(len));
if (0 != result)
{
std::memcpy(result, wkbstring.c_str(), len);
@@ -4732,7 +4776,7 @@
const std::size_t len = wkbstring.length();
unsigned char *result = NULL;
- result = (unsigned char*) std::malloc(len);
+ result = (unsigned char*) geos_alloc(len);
std::memcpy(result, wkbstring.c_str(), len);
*size = len;
return result;
@@ -4776,7 +4820,7 @@
const std::size_t len = wkbstring.length();
unsigned char *result = NULL;
- result = (unsigned char*) std::malloc(len);
+ result = (unsigned char*) geos_alloc(len);
std::memcpy(result, wkbstring.c_str(), len);
*size = len;
return result;
Added: trunk/include/geos/util/CustomAllocators.h
===================================================================
--- trunk/include/geos/util/CustomAllocators.h (rev 0)
+++ trunk/include/geos/util/CustomAllocators.h 2012-05-16 12:20:42 UTC (rev 3631)
@@ -0,0 +1,30 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2012 Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************/
+
+#include <cstdlib> // size_t
+
+namespace geos {
+namespace util {
+namespace CustomAllocators {
+
+ typedef void * (*GEOSAllocator) (std::size_t size);
+ GEOSAllocator setAllocator(GEOSAllocator nf);
+
+ typedef void (*GEOSFreer) (void *ptr);
+ GEOSFreer setFreer(GEOSFreer nf);
+
+}
+}
+}
+
Modified: trunk/include/geos/util/Makefile.am
===================================================================
--- trunk/include/geos/util/Makefile.am 2012-05-16 10:29:01 UTC (rev 3630)
+++ trunk/include/geos/util/Makefile.am 2012-05-16 12:20:42 UTC (rev 3631)
@@ -10,6 +10,7 @@
geos_HEADERS = \
Assert.h \
AssertionFailedException.h \
+ CustomAllocators.h \
CoordinateArrayFilter.h \
GeometricShapeFactory.h \
GEOSException.h \
Added: trunk/src/util/CustomAllocators.cpp
===================================================================
--- trunk/src/util/CustomAllocators.cpp (rev 0)
+++ trunk/src/util/CustomAllocators.cpp 2012-05-16 12:20:42 UTC (rev 3631)
@@ -0,0 +1,59 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2012 Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************/
+
+#include <geos/util/CustomAllocators.h>
+
+#include <new>
+#include <iostream>
+#include <cstdlib>
+
+namespace geos {
+namespace util {
+namespace CustomAllocators {
+
+GEOSAllocator geos_alloc = std::malloc;
+GEOSFreer geos_free = std::free;
+
+GEOSAllocator
+setAllocator(GEOSAllocator nf)
+{
+ GEOSAllocator of = geos_alloc;
+ geos_alloc = nf;
+ return of;
+}
+
+GEOSFreer
+setFreer(GEOSFreer nf)
+{
+ GEOSFreer of = geos_free;
+ geos_free = nf;
+ return of;
+}
+
+}
+}
+}
+
+
+void*
+operator new (std::size_t size, const std::nothrow_t&) throw () {
+ //std::cout << "...new(" << size << ") called" << std::endl;
+ return std::malloc(size);
+}
+
+void operator delete (void *ptr) throw () {
+ //std::cout << "...delete(" << ptr << ") called" << std::endl;
+ if ( ptr ) std::free(ptr);
+}
+
Modified: trunk/src/util/Makefile.am
===================================================================
--- trunk/src/util/Makefile.am 2012-05-16 10:29:01 UTC (rev 3630)
+++ trunk/src/util/Makefile.am 2012-05-16 12:20:42 UTC (rev 3631)
@@ -9,6 +9,7 @@
libutil_la_SOURCES = \
Assert.cpp \
+ CustomAllocators.cpp \
GeometricShapeFactory.cpp \
math.cpp \
Profiler.cpp
Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am 2012-05-16 10:29:01 UTC (rev 3630)
+++ trunk/tests/unit/Makefile.am 2012-05-16 12:20:42 UTC (rev 3631)
@@ -102,6 +102,7 @@
simplify/TopologyPreservingSimplifierTest.cpp \
util/UniqueCoordinateArrayFilterTest.cpp \
capi/GEOSCoordSeqTest.cpp \
+ capi/GEOSCustomAllocatorTest.cpp \
capi/GEOSGeomFromWKBTest.cpp \
capi/GEOSGeomToWKTTest.cpp \
capi/GEOSContainsTest.cpp \
Added: trunk/tests/unit/capi/GEOSCustomAllocatorTest.cpp
===================================================================
--- trunk/tests/unit/capi/GEOSCustomAllocatorTest.cpp (rev 0)
+++ trunk/tests/unit/capi/GEOSCustomAllocatorTest.cpp 2012-05-16 12:20:42 UTC (rev 3631)
@@ -0,0 +1,110 @@
+//
+// Test Suite for C-API custom allocators
+
+#include <tut.hpp>
+// geos
+#include <geos_c.h>
+// std
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <memory>
+
+namespace tut
+{
+ //
+ // Test Group
+ //
+
+ // Common data used in test cases.
+ struct test_capicustomallocators_data
+ {
+ static int alloc_count;
+
+ static void notice(const char *fmt, ...)
+ {
+ std::fprintf( stdout, "NOTICE: ");
+
+ va_list ap;
+ va_start(ap, fmt);
+ std::vfprintf(stdout, fmt, ap);
+ va_end(ap);
+
+ std::fprintf(stdout, "\n");
+ }
+
+ static void *t_alloc(size_t sz)
+ {
+ ++alloc_count;
+ void *ret = std::malloc(sz);
+ //notice("t_alloc(%d) returning %p", sz, ret);
+ return ret;
+ }
+
+ static void t_free(void *ptr)
+ {
+ //notice("t_free(%p)", ptr);
+ --alloc_count;
+ std::free(ptr);
+ }
+
+ test_capicustomallocators_data()
+ {
+ GEOS_setAllocator(t_alloc);
+ GEOS_setFreer(t_free);
+
+ alloc_count = 0;
+ }
+
+ ~test_capicustomallocators_data()
+ {
+ }
+
+ };
+
+ int test_capicustomallocators_data::alloc_count = 0;
+
+ typedef test_group<test_capicustomallocators_data> group;
+ typedef group::object object;
+
+ group test_capicustomallocators_group("capi::GEOSCustomAllocators");
+
+ //
+ // Test Cases
+ //
+
+ /// init and finish
+ template<>
+ template<>
+ void object::test<1>()
+ {
+ alloc_count = 0;
+
+ initGEOS(notice, notice);
+ finishGEOS();
+
+ ensure_equals(alloc_count, 0);
+ }
+
+ /// WKTReader
+ template<>
+ template<>
+ void object::test<2>()
+ {
+ alloc_count = 0;
+
+ initGEOS(notice, notice);
+
+ GEOSWKTReader* reader = GEOSWKTReader_create();
+ GEOSGeometry* g = GEOSWKTReader_read(reader, "POINT(0 0)");
+ GEOSGeom_destroy(g);
+ GEOSWKTReader_destroy(reader);
+
+ finishGEOS();
+
+ ensure_equals(alloc_count, 0);
+ }
+
+
+} // namespace tut
+
More information about the geos-commits
mailing list