├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── Dockerfile ├── LICENSE ├── README.md ├── TODO.txt ├── Vertex.xcodeproj ├── pavel.perspectivev3 └── project.pbxproj ├── docs └── manual.html ├── modules ├── FindEvent.cmake ├── FindTokyoCabinet.cmake └── FindYajl.cmake ├── source ├── RunningStat.c ├── RunningStat.h ├── Socket.c ├── Socket.h ├── VertexServer.c ├── VertexServer.h ├── VertexServer_amchart.c ├── VertexServer_extra.c ├── basekit │ ├── CMakeLists.txt │ ├── README.md │ ├── license │ │ └── bsd_license.txt │ └── source │ │ ├── BStream.c │ │ ├── BStream.h │ │ ├── BStreamTag.c │ │ ├── BStreamTag.h │ │ ├── Base.h │ │ ├── CHash.c │ │ ├── CHash.h │ │ ├── CHash_inline.h │ │ ├── Common.c │ │ ├── Common.h │ │ ├── Common_inline.h │ │ ├── Date.c │ │ ├── Date.h │ │ ├── Duration.c │ │ ├── Duration.h │ │ ├── DynLib.c │ │ ├── DynLib.h │ │ ├── Hash_fnv.c │ │ ├── Hash_fnv.h │ │ ├── Hash_murmur.c │ │ ├── Hash_murmur.h │ │ ├── Hash_superfast.c │ │ ├── Hash_superfast.h │ │ ├── List.c │ │ ├── List.h │ │ ├── List_inline.h │ │ ├── MainArgs.c │ │ ├── MainArgs.h │ │ ├── PointerHash.c │ │ ├── PointerHash.h │ │ ├── PointerHash_inline.h │ │ ├── PointerHash_struct.h │ │ ├── PortableGettimeofday.c │ │ ├── PortableGettimeofday.h │ │ ├── PortableSnprintf.c │ │ ├── PortableSorting.c │ │ ├── PortableSorting.h │ │ ├── PortableStdint.h │ │ ├── PortableStrlcpy.c │ │ ├── PortableStrlcpy.h │ │ ├── PortableStrptime.c │ │ ├── PortableStrptime.h │ │ ├── PortableTruncate.c │ │ ├── PortableTruncate.h │ │ ├── PortableUsleep.c │ │ ├── PortableUsleep.h │ │ ├── RandomGen.c │ │ ├── RandomGen.h │ │ ├── Stack.c │ │ ├── Stack.h │ │ ├── Stack_inline.h │ │ ├── UArray.c │ │ ├── UArray.h │ │ ├── UArray_character.c │ │ ├── UArray_character.h │ │ ├── UArray_format.c │ │ ├── UArray_format.h │ │ ├── UArray_math.c │ │ ├── UArray_math.h │ │ ├── UArray_path.c │ │ ├── UArray_path.h │ │ ├── UArray_stream.c │ │ ├── UArray_stream.h │ │ ├── UArray_string.c │ │ ├── UArray_string.h │ │ ├── UArray_utf.c │ │ ├── UArray_utf.h │ │ ├── _new │ │ └── Directory.c │ │ ├── cdecode.c │ │ ├── cdecode.h │ │ ├── cencode.c │ │ ├── cencode.h │ │ ├── simd_cph │ │ ├── LICENSE.txt │ │ ├── docs │ │ │ └── LICENSE.txt │ │ ├── include │ │ │ ├── simd_cp.h │ │ │ ├── simd_cp_arm-iwmmx.h │ │ │ ├── simd_cp_emu.h │ │ │ └── simd_cp_x86.h │ │ ├── simd_cph.readme │ │ └── test │ │ │ ├── Makefile │ │ │ ├── test_simd.c │ │ │ └── test_simd_emu │ │ ├── ucs2.c │ │ ├── ucs4.c │ │ ├── utf8.c │ │ ├── utf8.h │ │ ├── utf8internal.h │ │ ├── utf_convert.c │ │ └── utf_convert.h ├── httpserver │ ├── HttpRequest.c │ ├── HttpRequest.h │ ├── HttpResponse.c │ ├── HttpResponse.h │ ├── HttpServer.c │ └── HttpServer.h ├── main.c ├── pdb │ ├── Datum.c │ ├── Datum.h │ ├── File.c │ ├── File.h │ ├── Log.c │ ├── Log.h │ ├── PCollector.c │ ├── PCollector.h │ ├── PDB.c │ ├── PDB.h │ ├── PNode.c │ ├── PNode.h │ ├── PQuery.c │ ├── PQuery.h │ ├── Pointer.c │ ├── Pointer.h │ ├── Pool.c │ ├── Pool.h │ ├── Yajl_extras.c │ └── Yajl_extras.h └── store │ ├── Store.c │ ├── Store.h │ ├── StoreCursor.c │ └── StoreCursor.h ├── tests ├── db │ └── .gitisdumb ├── pnode.io ├── stress.io ├── test.io ├── test.py ├── urls.txt └── write_test.io ├── vertexdb.tmproj └── vertexdb_admin /.gitignore: -------------------------------------------------------------------------------- 1 | *.lib 2 | *.dll 3 | *.manifest 4 | *.obj 5 | *.exp 6 | *.ilk 7 | ._* 8 | *.pdb 9 | *.hi 10 | *.o 11 | *.so 12 | *.dylib 13 | *.cmd 14 | .mod.c* 15 | *.tmp_versions 16 | *CVS 17 | *RCS 18 | *IoVMCode.c* 19 | *Io*Init.c* 20 | ~* 21 | *_darcs 22 | *_build 23 | *_ioCodeProcessed 24 | *errors 25 | *.bak* 26 | *.BAK* 27 | *.orig* 28 | *vssver.scc* 29 | *.swp* 30 | *MT 31 | *\{arch\} 32 | *.arch-ids 33 | *, 34 | *.class* 35 | *.prof* 36 | *.DS_Store* 37 | *.FBCLockFolder 38 | *BitKeeper 39 | *ChangeSet 40 | *.svn 41 | .cvsignore* 42 | .gdb_history* 43 | *Thumbs.db* 44 | .DS_Store 45 | .libs 46 | .deps* 47 | *.a 48 | *.la 49 | *.lo 50 | *.so 51 | *.dylib 52 | *.exe 53 | *.Po 54 | *.Tlo 55 | *.Plo 56 | _objs 57 | _includes 58 | *_libs 59 | *Io.*Code.c* 60 | io2c 61 | *Io.*Init.c* 62 | *pngtest* 63 | *steve.model* 64 | *skipdbtest* 65 | *config.log* 66 | *config.status* 67 | .rej* 68 | *autom4te.cache* 69 | *.cache 70 | *_include 71 | *tags* 72 | ./addons/SGML/source/libsgml/Makefile* 73 | ./addons/SGML/source/libsgml/examples/Makefile* 74 | ./addons/SGML/source/libsgml/src/Makefile* 75 | tools/editlib_test/editlib_test 76 | extras/IoPlayers/MSWindows/ioplayer/ioplayer.ncb 77 | extras/IoPlayers/MSWindows/ioplayer/ioplayer.suo 78 | extras/IoPlayers/MSWindows/ioplayer/ioplayer/Debug 79 | extras/IoPlayers/MSWindows/ioplayer/ioplayer/Release 80 | extras/IoPlayers/MSWindows/ioplayer/ioplayer/ioplayer.vcproj.CUSTOMER2007.Customer.user 81 | extras/IoPlayers/MSWindows/ioplayer/pingme.txt 82 | extras/IoPlayers/MSWindows/ioplayer/smysrv 83 | libs/iovm/docs/docs.txt 84 | addons/*/docs/docs.txt 85 | *.mode1 86 | *.pbxuser 87 | *.mode1v3 88 | extras/osxvm/build 89 | *~ 90 | build 91 | tests/db/* 92 | !tests/db/.gitisdumb 93 | CMakeFiles 94 | CMakeCache.txt 95 | cmake_install.cmake 96 | install_manifest.txt 97 | Makefile 98 | vartexdb 99 | source/basekit/Makefile 100 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "source/basekit"] 2 | path = source/basekit 3 | url = git://github.com/stevedekorte/basekit.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(vertexdb) 4 | 5 | add_subdirectory(source/basekit) 6 | add_definitions(-O0 -g) 7 | 8 | set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/modules/") 9 | 10 | file(GLOB MAIN_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.c") 11 | file(GLOB PDB_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/source/pdb/*.c") 12 | file(GLOB BASEKIT_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/source/basekit/source/*.c") 13 | file(GLOB STORE_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/source/store/*.c") 14 | file(GLOB HTTPSERVER_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/source/httpserver/*.c") 15 | file(GLOB BASEKIT_SIMD_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/source/basekit/source/simd_cph/include") 16 | 17 | set(SRCS ${MAIN_SRCS} ${PDB_SRCS} ${BASEKIT_SRCS} ${STORE_SRCS} ${HTTPSERVER_SRCS} ${BASEKIT_SIMD_SRCS}) 18 | 19 | add_executable(vertexdb ${SRCS}) 20 | 21 | # Initializing libEvent 22 | find_package(Event) 23 | target_link_libraries(vertexdb ${EVENT_LIBRARY}) 24 | include_directories(${EVENT_INCLUDE_DIR}) 25 | 26 | # Initializing TokyoCabinet 27 | find_package(TokyoCabinet) 28 | target_link_libraries(vertexdb ${TOKYOCABINET_LIBRARY}) 29 | include_directories(${TOKYOCABINET_INCLUDE_DIR}) 30 | 31 | # Initializing YAJL 32 | find_package(Yajl) 33 | target_link_libraries(vertexdb ${YAJL_LIBRARY}) 34 | include_directories(${YAJL_INCLUDE_DIR}) 35 | 36 | # Add libdl 37 | find_library( DL_LIB NAMES ${CMAKE_DL_LIBS} ) 38 | target_link_libraries(vertexdb ${CMAKE_DL_LIBS}) 39 | MESSAGE( STATUS "using dl library: ${DL_LIB}" ) 40 | 41 | target_link_libraries(vertexdb m) 42 | MESSAGE( STATUS "using m library from the standard glibc") 43 | 44 | include_directories(source source/pdb source/httpserver source/basekit/source source/store source/basekit/source/simd_cph/include) 45 | 46 | # installing vertextdb binary 47 | install(TARGETS vertexdb DESTINATION bin) 48 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:latest 2 | 3 | ENV OPTS "" 4 | RUN apt-get update && apt-get install --force-yes -y cmake \ 5 | git \ 6 | apt-utils \ 7 | libtokyocabinet-dev \ 8 | zip \ 9 | libyajl-dev \ 10 | libyajl2 \ 11 | libevent-dev 12 | 13 | RUN gem update --no-rdoc --no-ri && gem install --no-rdoc --no-ri \ 14 | yajl \ 15 | yajl-ruby \ 16 | zipruby \ 17 | libevent 18 | 19 | 20 | RUN git clone https://github.com/stevedekorte/vertexdb.git vertexdb 21 | 22 | WORKDIR vertexdb 23 | 24 | RUN cmake . &&\ 25 | make &&\ 26 | make install 27 | 28 | EXPOSE 8080 29 | 30 | ENTRYPOINT ["/usr/local/bin/vertexdb"] 31 | CMD ["-db", "/opt/database", "--pid", "/var/run/vertex.pid", "-H", "0.0.0.0", "-p", "80", "$OPTS"] 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/vertexdb/8fbb2fa0a750bb100a8d6563fefa7721ee2b6b02/LICENSE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Vertex is a high performance graph database that supports automatic garbage collection, built on libevent and tokyocabinet. It uses HTTP as its communication protocol and JSON as its response data format. It's BSD licensed and was written by Steve Dekorte and Rich Collins. 4 | See `docs/manual.html` for API and more details. 5 | 6 | # Status 7 | 8 | Currently in production use and working well so far. The API is still not set in stone though. 9 | 10 | # Usage 11 | Compiling on Mac OS X 12 | 13 | sudo port install yajl tokyocabinet libevent libzip 14 | # or if you are using homebrew 15 | brew install yajl tokyo-cabinet libevent 16 | cmake . 17 | make 18 | sudo make install 19 | 20 | If all was fine, in build/vertexdb will be bin file 21 | 22 | Running 23 | 24 | vertexdb -db blog1.db 25 | 26 | or as daemon 27 | 28 | sudo vertexdb -db /opt/database -d --pid /var/run/vertex.pid 29 | 30 | Possible options: 31 | 32 | --database -db Database file 33 | --port -p TCP port number to listen on (default: 8080) 34 | --host -H Network interface to listen (default: 127.0.0.1) 35 | --daemon -d Run as a daemon 36 | --log Log file location 37 | --pid Pid file location 38 | --debug Be more verbose 39 | --hardsync Run with hard syncronization 40 | --help -h Show this help 41 | 42 | # Future 43 | 44 | May add support for more complex queries and dynamic/automatic index creation based on observed queries. 45 | 46 | # Dynamic languages support 47 | 48 | * ruby - comming soon (or ask in pm) 49 | 50 | 51 | # Docker Support 52 | 53 | If you have [Docker](https://www.docker.com/) installed, you can build a Docker image and run it in a container 54 | 55 | ``` 56 | docker build -t vertexdb . # build 57 | docker run -d -p 8080:80 --name myVertexdb vertexdb # running on PORT 8080 (On MAC, the IP address of the container is given via Kitematic) 58 | ``` 59 | 60 | or get an image of `vertexdb` directly from the Docker Hub 61 | 62 | ``` 63 | docker run -d -p 8080:80 -e OPTS="" --name myVertexdb earvin/vertexdb 64 | ``` 65 | 66 | OPTS could be 67 | 68 | - "--hardsync", 69 | - "--debug", 70 | - both or "" 71 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | 2 | ToDo 3 | 4 | - add tests to tests.io 5 | - error conditions (highest priority) 6 | - rm 7 | - transactions 8 | - collect garbage 9 | - backup 10 | - shutdown 11 | - queuePopTo ttl 12 | - chmod 13 | - chown 14 | - stat 15 | - stats 16 | - login? 17 | - newuser? (lowest priority) 18 | 19 | - add http basic auth 20 | 21 | - make sure docs are in sync with code 22 | 23 | - add performance tests for: 24 | - writes, removes, reads per second 25 | - db size per number of writes 26 | - possibly look into tokyocabinet tuning parameters 27 | 28 | - FUSE interface 29 | 30 | - start project to reimplement vertexdb in Lua or Javascript v8 with async sockets & tokyocabinet - this would allow us to use Lua or JS as a query language 31 | -------------------------------------------------------------------------------- /docs/manual.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/vertexdb/8fbb2fa0a750bb100a8d6563fefa7721ee2b6b02/docs/manual.html -------------------------------------------------------------------------------- /modules/FindEvent.cmake: -------------------------------------------------------------------------------- 1 | # Base Io build system 2 | # Written by Jeremy Tregunna 3 | # 4 | # Find libevent. 5 | 6 | FIND_PATH(EVENT_INCLUDE_DIR event.h) 7 | 8 | SET(EVENT_NAMES ${EVENT_NAMES} event libevent) 9 | FIND_LIBRARY(EVENT_LIBRARY NAMES ${EVENT_NAMES} PATH) 10 | 11 | IF(EVENT_INCLUDE_DIR AND EVENT_LIBRARY) 12 | SET(EVENT_FOUND TRUE) 13 | ENDIF(EVENT_INCLUDE_DIR AND EVENT_LIBRARY) 14 | 15 | IF(EVENT_FOUND) 16 | IF(NOT Event_FIND_QUIETLY) 17 | MESSAGE(STATUS "Found Event: ${EVENT_LIBRARY}") 18 | ENDIF (NOT Event_FIND_QUIETLY) 19 | ELSE(EVENT_FOUND) 20 | IF(Event_FIND_REQUIRED) 21 | MESSAGE(FATAL_ERROR "Could not find event") 22 | ENDIF(Event_FIND_REQUIRED) 23 | ENDIF (EVENT_FOUND) -------------------------------------------------------------------------------- /modules/FindTokyoCabinet.cmake: -------------------------------------------------------------------------------- 1 | # Base Io build system 2 | # Written by Jeremy Tregunna 3 | # 4 | # Find libtokyocabinet. 5 | 6 | FIND_PATH(TOKYOCABINET_INCLUDE_DIR tcutil.h tcbdb.h) 7 | 8 | SET(TOKYOCABINET_NAMES ${TOKYOCABINET_NAMES} tokyocabinet libtokyocabinet) 9 | FIND_LIBRARY(TOKYOCABINET_LIBRARY NAMES ${TOKYOCABINET_NAMES} PATH) 10 | 11 | IF(TOKYOCABINET_INCLUDE_DIR AND TOKYOCABINET_LIBRARY) 12 | SET(TOKYOCABINET_FOUND TRUE) 13 | ENDIF(TOKYOCABINET_INCLUDE_DIR AND TOKYOCABINET_LIBRARY) 14 | 15 | IF(TOKYOCABINET_FOUND) 16 | IF(NOT TokyoCabinet_FIND_QUIETLY) 17 | MESSAGE(STATUS "Found TokyoCabinet: ${TOKYOCABINET_LIBRARY}") 18 | ENDIF (NOT TokyoCabinet_FIND_QUIETLY) 19 | ELSE(TOKYOCABINET_FOUND) 20 | IF(TokyoCabinet_FIND_REQUIRED) 21 | MESSAGE(FATAL_ERROR "Could not find tokyocabinet") 22 | ENDIF(TokyoCabinet_FIND_REQUIRED) 23 | ENDIF (TOKYOCABINET_FOUND) -------------------------------------------------------------------------------- /modules/FindYajl.cmake: -------------------------------------------------------------------------------- 1 | # Base Io build system 2 | # Written by Jeremy Tregunna 3 | # 4 | # Find libyajl 5 | 6 | FIND_PATH(YAJL_INCLUDE_DIR yajl/yajl_common.h) 7 | 8 | SET(YAJL_NAMES ${YAJL_NAMES} yajl libyajl) 9 | FIND_LIBRARY(YAJL_LIBRARY NAMES ${YAJL_NAMES} PATH) 10 | 11 | IF(YAJL_INCLUDE_DIR AND YAJL_LIBRARY) 12 | SET(YAJL_FOUND TRUE) 13 | ENDIF(YAJL_INCLUDE_DIR AND YAJL_LIBRARY) 14 | 15 | IF(YAJL_FOUND) 16 | IF(NOT Yajl_FIND_QUIETLY) 17 | MESSAGE(STATUS "Found Yajl: ${YAJL_LIBRARY}") 18 | ENDIF (NOT Yajl_FIND_QUIETLY) 19 | ELSE(YAJL_FOUND) 20 | IF(Yajl_FIND_REQUIRED) 21 | MESSAGE(FATAL_ERROR "Could not find yajl") 22 | ENDIF(Yajl_FIND_REQUIRED) 23 | ENDIF(YAJL_FOUND) 24 | -------------------------------------------------------------------------------- /source/RunningStat.c: -------------------------------------------------------------------------------- 1 | #include "RunningStat.h" 2 | #include "Log.h" 3 | #include "Date.h" 4 | #include 5 | #include 6 | #include 7 | 8 | RunningStat *RunningStat_new(void) 9 | { 10 | RunningStat *self = calloc(1, sizeof(RunningStat)); 11 | RunningStat_setSampleCount_(self, 100); 12 | self->startDate = Date_new(); 13 | Date_now(self->startDate); 14 | return self; 15 | } 16 | 17 | void RunningStat_free(RunningStat *self) 18 | { 19 | free(self->times); 20 | Date_free(self->startDate); 21 | free(self); 22 | } 23 | 24 | void RunningStat_setSamplesTo_(RunningStat *self, size_t dt) 25 | { 26 | int i; 27 | 28 | for (i = 0; i < self->sampleCount; i ++) 29 | { 30 | self->times[i] = dt; 31 | } 32 | 33 | self->runningSum = dt * self->sampleCount; 34 | } 35 | 36 | void RunningStat_setSampleCount_(RunningStat *self, size_t count) 37 | { 38 | self->sampleCount = count; 39 | self->times = realloc(self->times, count * sizeof(size_t)); 40 | RunningStat_setSamplesTo_(self, 0); 41 | self->started = 0; 42 | } 43 | 44 | size_t RunningStat_sampleCount(RunningStat *self) 45 | { 46 | return self->sampleCount; 47 | } 48 | 49 | void RunningStat_startTimer(RunningStat *self) 50 | { 51 | self->t1 = Date_secondsSinceNow(self->startDate); 52 | } 53 | 54 | void RunningStat_stopTimer(RunningStat *self) 55 | { 56 | size_t dt = (size_t)((Date_secondsSinceNow(self->startDate) - self->t1) * 1000000.0); 57 | 58 | if (!self->started) 59 | { 60 | self->started = 1; 61 | RunningStat_setSamplesTo_(self, dt); 62 | } 63 | else 64 | { 65 | self->runningSum -= self->times[self->index]; 66 | self->times[self->index] = dt; 67 | self->runningSum += self->times[self->index]; 68 | } 69 | 70 | self->index ++; 71 | self->index = self->index % self->sampleCount; 72 | } 73 | 74 | double RunningStat_aveTime(RunningStat *self) 75 | { 76 | return ((double)self->runningSum / (double)self->sampleCount)/1000000.0; 77 | } 78 | 79 | double RunningStat_lastTime(RunningStat *self) 80 | { 81 | int i = self->index - 1; 82 | if (i == -1) i = self->sampleCount - 1; 83 | return ((double)self->times[i])/1000000.0; 84 | } 85 | -------------------------------------------------------------------------------- /source/RunningStat.h: -------------------------------------------------------------------------------- 1 | #ifndef RunningStat_DEFINED 2 | #define RunningStat_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include "Date.h" 11 | 12 | typedef struct 13 | { 14 | size_t sampleCount; 15 | int started; 16 | int index; 17 | size_t *times; 18 | double t1; 19 | size_t runningSum; // in microseconds 20 | Date *startDate; 21 | } RunningStat; 22 | 23 | RunningStat *RunningStat_new(void); 24 | void RunningStat_free(RunningStat *self); 25 | void RunningStat_setSampleCount_(RunningStat *self, size_t count); 26 | size_t RunningStat_sampleCount(RunningStat *self); 27 | void RunningStat_startTimer(RunningStat *self); 28 | void RunningStat_stopTimer(RunningStat *self); 29 | double RunningStat_aveTime(RunningStat *self); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | #endif 35 | -------------------------------------------------------------------------------- /source/Socket.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | 17 | long Socket_SetDescriptorLimitToMax(void) 18 | { 19 | struct rlimit rlp; 20 | 21 | // if were root, we could also do: 22 | // system("sysctl -w kern.maxfiles=1000001"); 23 | // system("sysctl -w kern.maxfilesperproc=1000000"); 24 | 25 | /* 26 | int optval = 1; 27 | int 28 | setsockopt(int socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); 29 | SO_REUSEADDR 30 | */ 31 | 32 | if (getrlimit(RLIMIT_NOFILE, &rlp) != 0) 33 | { 34 | return -1; 35 | } 36 | 37 | printf("rlp.rlim_cur = %i\n", (int)rlp.rlim_cur); 38 | printf("rlp.rlim_max = %i\n", (int)rlp.rlim_max); 39 | 40 | rlp.rlim_cur = rlp.rlim_max; 41 | 42 | if (setrlimit(RLIMIT_NOFILE, &rlp) != 0) 43 | { 44 | return -2; 45 | } 46 | 47 | if (getrlimit(RLIMIT_NOFILE, &rlp) != 0) 48 | { 49 | return -3; 50 | } 51 | 52 | printf(" max listeners = %i\n", (int)rlp.rlim_cur); 53 | 54 | return (long)(rlp.rlim_cur); 55 | } 56 | -------------------------------------------------------------------------------- /source/Socket.h: -------------------------------------------------------------------------------- 1 | 2 | long Socket_SetDescriptorLimitToMax(void); 3 | -------------------------------------------------------------------------------- /source/VertexServer.h: -------------------------------------------------------------------------------- 1 | #include "PDB.h" 2 | #include "List.h" 3 | #include "CHash.h" 4 | #include "Yajl_extras.h" 5 | #include "yajl/yajl_common.h" 6 | #include "HttpServer.h" 7 | 8 | typedef struct 9 | { 10 | // the database 11 | PDB *pdb; 12 | 13 | // the http server 14 | HttpServer *httpServer; 15 | HttpRequest *httpRequest; 16 | HttpResponse *httpResponse; 17 | Datum *result; // used for composing the response string 18 | // the global json generator 19 | yajl_gen yajl; 20 | 21 | // hash table of VertextServer action function pointers 22 | CHash *actions; 23 | // hash table of PNode op function pointers 24 | CHash *ops; 25 | 26 | // daemon related 27 | int isDaemon; 28 | const char *pidPath; 29 | int debug; 30 | } VertexServer; 31 | 32 | typedef int (VertexAction)(VertexServer *); 33 | 34 | VertexServer *VertexServer_new(void); 35 | void VertexServer_free(VertexServer *self); 36 | 37 | // private 38 | void VertexServer_setupPQuery_(VertexServer *self, PQuery *q); 39 | void VertexServer_setErrorCString_(VertexServer *self, const char *s); 40 | void VertexServer_appendError_(VertexServer *self, Datum *d); 41 | 42 | // command line options 43 | void VertexServer_setPort_(VertexServer *self, int port); 44 | void VertexServer_setHost_(VertexServer *self, char *host); 45 | void VertexServer_setDbPath_(VertexServer *self, char *path); 46 | void VertexServer_setLogPath_(VertexServer *self, const char *path); 47 | void VertexServer_setPidPath_(VertexServer *self, const char *path); 48 | void VertexServer_setIsDaemon_(VertexServer *self, int isDaemon); 49 | void VertexServer_setDebug_(VertexServer *self, int aBool); 50 | void VertexServer_setHardSync_(VertexServer *self, int aBool); 51 | 52 | // request processing 53 | int VertexServer_process(VertexServer *self); 54 | int VertexServer_run(VertexServer *self); 55 | int VertexServer_shutdown(VertexServer *self); 56 | void VertexServer_requestHandler(void *arg); 57 | 58 | // apis 59 | int VertexServer_api_collectGarbage(VertexServer *self); 60 | int VertexServer_api_shutdown(VertexServer *self); 61 | -------------------------------------------------------------------------------- /source/VertexServer_amchart.c: -------------------------------------------------------------------------------- 1 | #include "VertexServer.h" 2 | #include "Date.h" 3 | #include "Socket.h" 4 | #include "PQuery.h" 5 | 6 | int VertexServer_api_amchart(VertexServer *self) 7 | { 8 | Datum *slot1 = HttpRequest_queryValue_(self->httpRequest, "slot1"); 9 | //Datum *slot2 = HttpRequest_queryValue_(self->httpRequest, "slot2"); 10 | //Datum *slot3 = HttpRequest_queryValue_(self->httpRequest, "slot3"); 11 | Datum *subpath = HttpRequest_queryValue_(self->httpRequest, "subpath"); 12 | PNode *node = PDB_allocNode(self->pdb); 13 | PQuery *q = PNode_query(node); 14 | VertexServer_setupPQuery_(self, q); 15 | PNode *tmpNode = PDB_allocNode(self->pdb); 16 | Datum *d = self->result; 17 | Datum *title = 0x0; 18 | //int isFirst = 1; 19 | 20 | if (PNode_moveToPathIfExists_(node, HttpRequest_uriPath(self->httpRequest)) != 0) 21 | { 22 | VertexServer_setErrorCString_(self, "path does not exist: "); 23 | VertexServer_appendError_(self, HttpRequest_uriPath(self->httpRequest)); 24 | return -1; 25 | } 26 | 27 | Datum_appendCString_(d, "\n"); 28 | Datum_appendCString_(d, "\n"); 34 | PNode_startQuery(node); 35 | PNode_amSeries(node, d); 36 | PNode_moveToPathIfExists_(node, HttpRequest_uriPath(self->httpRequest)); 37 | // series ----------------- 38 | 39 | Datum_appendCString_(d, "\n"); 40 | PNode_first(node); 41 | 42 | if(Datum_size(subpath)) 43 | { 44 | Datum *k; 45 | 46 | while((k = PNode_key(node))) 47 | { 48 | Datum *title = Datum_poolNew(); 49 | PNode_setPid_(tmpNode, PNode_value(node)); 50 | PNode_moveToSubpathIfExists_(tmpNode, subpath); 51 | Datum_encodeUri(k); 52 | 53 | Datum_copy_(title, k); 54 | //Datum_appendCString_(title, "-"); 55 | //Datum_append_(title, slot1); 56 | 57 | PNode_amGraphKey_(tmpNode, title, slot1, d); 58 | //printf("graph: %s\n", Datum_data(k)); 59 | PNode_next(node); 60 | } 61 | 62 | } 63 | else if(Datum_size(slot1)) 64 | { 65 | char slotKey[64]; 66 | int slotNumber = 1; 67 | 68 | for (;;) 69 | { 70 | sprintf(slotKey, "slot%i", slotNumber); 71 | 72 | Datum *slotName = HttpRequest_queryValue_(self->httpRequest, slotKey); 73 | if(Datum_size(slotName) == 0) break; 74 | PNode_amGraphKey_(node, title, slotName, d); 75 | slotNumber ++; 76 | 77 | } 78 | } 79 | 80 | 81 | Datum_appendCString_(d, "\n"); 82 | Datum_appendCString_(d, "\n"); 83 | 84 | HttpResponse_setContentType_(self->httpResponse, "text/xml"); 85 | //HttpResponse_setContentType_(self->httpResponse, "text/xml; charset=utf-8"); 86 | return 0; 87 | } 88 | 89 | 90 | int VertexServer_api_ampie(VertexServer *self) 91 | { 92 | Datum *slot1 = HttpRequest_queryValue_(self->httpRequest, "slot1"); 93 | //Datum *slot2 = HttpRequest_queryValue_(self->httpRequest, "slot2"); 94 | //Datum *slot3 = HttpRequest_queryValue_(self->httpRequest, "slot3"); 95 | //Datum *subpath = HttpRequest_queryValue_(self->httpRequest, "subpath"); 96 | PNode *node = PDB_allocNode(self->pdb); 97 | PQuery *q = PNode_query(node); 98 | VertexServer_setupPQuery_(self, q); 99 | PNode *tmpNode = PDB_allocNode(self->pdb); 100 | Datum *d = self->result; 101 | Datum *k; 102 | 103 | if (PNode_moveToPathIfExists_(node, HttpRequest_uriPath(self->httpRequest)) != 0) 104 | { 105 | VertexServer_setErrorCString_(self, "path does not exist: "); 106 | VertexServer_appendError_(self, HttpRequest_uriPath(self->httpRequest)); 107 | return -1; 108 | } 109 | 110 | //PNode_startQuery(node); 111 | 112 | PNode_first(node); 113 | while((k = PNode_key(node))) 114 | { 115 | PNode_setPid_(tmpNode, PNode_value(node)); 116 | Datum *v = PNode_at_(tmpNode, slot1); 117 | 118 | if(v) 119 | { 120 | Datum_append_(d, k); 121 | Datum_appendCString_(d, ";"); 122 | Datum_append_(d, v); 123 | Datum_appendCString_(d, "\n"); 124 | } 125 | 126 | PNode_next(node); 127 | } 128 | 129 | HttpResponse_setContentType_(self->httpResponse, "text/plain"); 130 | //HttpResponse_setContentType_(self->httpResponse, "text/xml; charset=utf-8"); 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /source/VertexServer_extra.c: -------------------------------------------------------------------------------- 1 | /* 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void VertexServer_serveFile_(VertexServer *self, const char *path) 8 | { 9 | Datum_copy_(self->filePath, self->staticPath); 10 | Datum_appendCString_(self->filePath, path); 11 | 12 | printf("file request: %s\n", Datum_data(self->filePath)); 13 | 14 | { 15 | int fd = open(Datum_data(self->filePath), O_RDONLY); 16 | evbuffer_read(self->buf, fd, 100000); 17 | close(fd); 18 | } 19 | 20 | VertexServer_sendOk(self); 21 | } 22 | */ 23 | -------------------------------------------------------------------------------- /source/basekit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Base Io build system 2 | # Written by Jeremy Tregunna 3 | # 4 | # Build the garbage collector library. 5 | 6 | # Output our dynamic library to the top-level _build hierarchy 7 | set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/_build/dll) 8 | 9 | # Marvelous flags, likely compiler dependent. 10 | add_definitions("-DBUILDING_BASEKIT_DLL") 11 | 12 | # Include dirs, -I flags and whatnot 13 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source/simd_cph/include) 14 | 15 | # Our library sources. 16 | file(GLOB SRCS "source/*.c") 17 | 18 | # Now build the shared library 19 | #add_library(basekit SHARED ${SRCS}) 20 | 21 | # ...And the static library 22 | #add_library(basekit_static STATIC ${SRCS}) 23 | 24 | # The following add the install target, so we put libbasekit.* in our 25 | # install prefix. 26 | #install(TARGETS basekit DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) -------------------------------------------------------------------------------- /source/basekit/README.md: -------------------------------------------------------------------------------- 1 | # Basekit 2 | 3 | Author: Stive Dekorte 4 | GitHub: http://github.com/stevedekorte/basekit 5 | About: http://www.dekorte.com/projects/opensource/libbasekit/ -------------------------------------------------------------------------------- /source/basekit/license/bsd_license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/vertexdb/8fbb2fa0a750bb100a8d6563fefa7721ee2b6b02/source/basekit/license/bsd_license.txt -------------------------------------------------------------------------------- /source/basekit/source/BStream.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright 3 | Steve Dekorte, 2004 4 | license 5 | BSD revised 6 | description 7 | A Binary Stream that supports tagged items. 8 | */ 9 | 10 | #ifndef BSTREAM_DEFINED 11 | #define BSTREAM_DEFINED 1 12 | 13 | #include "Common.h" 14 | #include "UArray.h" 15 | #include "BStreamTag.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | //typedef struct UArray UArray; 22 | 23 | typedef struct 24 | { 25 | UArray *ba; 26 | size_t index; 27 | unsigned char ownsUArray; 28 | UArray *tmp; 29 | UArray *errorBa; 30 | int flipEndian; 31 | unsigned char *typeBuf; 32 | } BStream; 33 | 34 | /* 35 | #define BStream_ba_(self, v) self->ba = v; 36 | #define BStream_ba(self) (self->ba) 37 | 38 | #define BStream_index_(self, v) self->index = v; 39 | #define BStream_index(self) (self->index) 40 | 41 | #define BStream_ownsUArray_(self, v) self->ownsUArray = v; 42 | #define BStream_ownsUArray(self) (self->ownsUArray) 43 | 44 | #define BStream_tmp_(self, v) self->tmp = v; 45 | #define BStream_tmp(self) (self->tmp) 46 | 47 | #define BStream_errorBa_(self, v) self->errorBa = v; 48 | #define BStream_errorBa(self) (self->errorBa) 49 | 50 | #define BStream_flipEndian_(self, v) self->flipEndian = v; 51 | #define BStream_flipEndian(self) (self->flipEndian) 52 | 53 | #define BStream_typeBuf_(self, v) self->typeBuf = v; 54 | #define BStream_typeBufs(self) (self->typeBuf) 55 | */ 56 | 57 | BASEKIT_API BStream *BStream_new(void); 58 | BASEKIT_API BStream *BStream_clone(BStream *self); 59 | BASEKIT_API void BStream_free(BStream *self); 60 | 61 | BASEKIT_API char *BStream_errorString(BStream *self); 62 | BASEKIT_API void BStream_setUArray_(BStream *self, UArray *ba); 63 | BASEKIT_API void BStream_setData_length_(BStream *self, unsigned char *data, size_t length); 64 | BASEKIT_API UArray *BStream_byteArray(BStream *self); 65 | BASEKIT_API void BStream_empty(BStream *self); 66 | BASEKIT_API int BStream_isEmpty(BStream *self); 67 | 68 | // writing -------------------------------------- 69 | 70 | BASEKIT_API void BStream_writeByte_(BStream *self, unsigned char v); 71 | 72 | BASEKIT_API void BStream_writeUint8_(BStream *self, uint8_t v); 73 | BASEKIT_API void BStream_writeUint32_(BStream *self, uint32_t v); 74 | BASEKIT_API void BStream_writeInt32_(BStream *self, int32_t v); 75 | #if !defined(__SYMBIAN32__) 76 | BASEKIT_API void BStream_writeInt64_(BStream *self, int64_t v); 77 | #endif 78 | BASEKIT_API void BStream_writeDouble_(BStream *self, double v); 79 | BASEKIT_API void BStream_writeData_length_(BStream *self, const unsigned char *data, size_t length); 80 | BASEKIT_API void BStream_writeCString_(BStream *self, const char *s); 81 | BASEKIT_API void BStream_writeUArray_(BStream *self, UArray *ba); 82 | 83 | // reading -------------------------------------- 84 | 85 | BASEKIT_API unsigned char BStream_readByte(BStream *self); 86 | 87 | BASEKIT_API uint8_t BStream_readUint8(BStream *self); 88 | BASEKIT_API uint32_t BStream_readUint32(BStream *self); 89 | BASEKIT_API int32_t BStream_readInt32(BStream *self); 90 | #if !defined(__SYMBIAN32__) 91 | BASEKIT_API int64_t BStream_readInt64(BStream *self); 92 | #endif 93 | BASEKIT_API double BStream_readDouble(BStream *self); 94 | BASEKIT_API uint8_t *BStream_readDataOfLength_(BStream *self, size_t length); 95 | BASEKIT_API void BStream_readUArray_(BStream *self, UArray *b); 96 | BASEKIT_API UArray *BStream_readUArray(BStream *self); 97 | BASEKIT_API const char *BStream_readCString(BStream *self); 98 | 99 | // tagged writing -------------------------------------- 100 | 101 | BASEKIT_API void BStream_writeTaggedUint8_(BStream *self, uint8_t v); 102 | BASEKIT_API void BStream_writeTaggedUint32_(BStream *self, uint32_t v); 103 | BASEKIT_API void BStream_writeTaggedInt32_(BStream *self, int32_t v); 104 | #if !defined(__SYMBIAN32__) 105 | BASEKIT_API void BStream_writeTaggedInt64_(BStream *self, int64_t v); 106 | #endif 107 | BASEKIT_API void BStream_writeTaggedDouble_(BStream *self, double v); 108 | BASEKIT_API void BStream_writeTaggedData_length_(BStream *self, const unsigned char *data, size_t length); 109 | BASEKIT_API void BStream_writeTaggedCString_(BStream *self, const char *s); 110 | BASEKIT_API void BStream_writeTaggedUArray_(BStream *self, UArray *ba); 111 | 112 | // tagged reading -------------------------------------- 113 | 114 | BASEKIT_API uint8_t BStream_readTaggedUint8(BStream *self); 115 | BASEKIT_API uint32_t BStream_readTaggedUint32(BStream *self); 116 | BASEKIT_API int32_t BStream_readTaggedInt32(BStream *self); 117 | #if !defined(__SYMBIAN32__) 118 | BASEKIT_API int64_t BStream_readTaggedInt64(BStream *self); 119 | #endif 120 | BASEKIT_API double BStream_readTaggedDouble(BStream *self); 121 | BASEKIT_API void BStream_readTaggedUArray_(BStream *self, UArray *b); 122 | BASEKIT_API UArray *BStream_readTaggedUArray(BStream *self); 123 | BASEKIT_API const char *BStream_readTaggedCString(BStream *self); 124 | 125 | BASEKIT_API void BStream_show(BStream *self); 126 | 127 | #ifdef __cplusplus 128 | } 129 | #endif 130 | #endif 131 | 132 | -------------------------------------------------------------------------------- /source/basekit/source/BStreamTag.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright 3 | Steve Dekorte, 2004 4 | license 5 | BSD revised 6 | */ 7 | 8 | #include "BStreamTag.h" 9 | #include 10 | 11 | /* 12 | unsigned int isArray : 1; 13 | unsigned int type : 2; 14 | unsigned int byteCount : 5; 15 | */ 16 | 17 | BStreamTag BStreamTag_FromUnsignedChar(unsigned char c) 18 | { 19 | // we need to do this because bit fields are compiler dependent 20 | BStreamTag t; 21 | t.isArray = c >> 7; 22 | t.type = ( c << 1) >> 6; 23 | t.byteCount = ( c << 3 ) >> 3; 24 | return t; 25 | } 26 | 27 | unsigned char BStreamTag_asUnsignedChar(BStreamTag *self) 28 | { 29 | BStreamTag t = *self; 30 | unsigned char c = 0; 31 | c = c | t.isArray << 7; 32 | c = c | t.type << 5; 33 | c = c | t.byteCount; 34 | return c; 35 | } 36 | 37 | // ----------------------------------------------------- 38 | 39 | BStreamTag BStreamTag_TagArray_type_byteCount_(unsigned int a, unsigned int t, unsigned int b) 40 | { 41 | BStreamTag self; 42 | self.isArray = a; 43 | self.type = t; 44 | self.byteCount = b; 45 | return self; 46 | } 47 | 48 | int BStreamTag_isEqual_(BStreamTag *self, BStreamTag *other) 49 | { 50 | return (BStreamTag_asUnsignedChar(self) == BStreamTag_asUnsignedChar(other)); 51 | } 52 | 53 | void BStreamTag_print(BStreamTag *self) 54 | { 55 | printf("[Tag "); 56 | printf("isArray: %i ", self->isArray); 57 | printf("type: %i ", self->type); 58 | printf("byteCount: %i", self->byteCount); 59 | printf("]"); 60 | } 61 | 62 | char *BStreamTag_typeName(BStreamTag *self) 63 | { 64 | switch (self->type) 65 | { 66 | case BSTREAM_UNSIGNED_INT: 67 | return "uint"; 68 | case BSTREAM_SIGNED_INT: 69 | return "int"; 70 | case BSTREAM_FLOAT: 71 | return "float"; 72 | case BSTREAM_POINTER: 73 | return "pointer"; 74 | } 75 | 76 | return "UNKNOWN TYPE"; 77 | } 78 | -------------------------------------------------------------------------------- /source/basekit/source/BStreamTag.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright 3 | Steve Dekorte, 2004 4 | license 5 | BSD revised 6 | */ 7 | 8 | #ifndef BSTREAMTAG_DEFINED 9 | #define BSTREAMTAG_DEFINED 1 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #define BSTREAM_UNSIGNED_INT 0 16 | #define BSTREAM_SIGNED_INT 1 17 | #define BSTREAM_FLOAT 2 18 | #define BSTREAM_POINTER 3 19 | 20 | typedef struct 21 | { 22 | unsigned int isArray : 1; 23 | unsigned int type : 2; // 0 = unsigned int, 1 = signed int, 2 = float, 3 = pointer 24 | unsigned int byteCount : 5; // number of bytes in data value(s) 25 | } BStreamTag; 26 | 27 | // values in network byte order / big endian 28 | 29 | BStreamTag BStreamTag_FromUnsignedChar(unsigned char c); 30 | unsigned char BStreamTag_asUnsignedChar(BStreamTag *self); 31 | BStreamTag BStreamTag_TagArray_type_byteCount_(unsigned int a, unsigned int t, unsigned int b); 32 | int BStreamTag_isEqual_(BStreamTag *self, BStreamTag *other); 33 | void BStreamTag_print(BStreamTag *self); 34 | 35 | char *BStreamTag_typeName(BStreamTag *self); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /source/basekit/source/Base.h: -------------------------------------------------------------------------------- 1 | #ifndef IOBASE_DEFINED 2 | #define IOBASE_DEFINED 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /source/basekit/source/CHash.h: -------------------------------------------------------------------------------- 1 | //metadoc CHash copyright Steve Dekorte 2009 2 | //metadoc CHash license BSD revised 3 | 4 | #ifndef CHASH_DEFINED 5 | #define CHASH_DEFINED 1 6 | 7 | #include "Common.h" 8 | #include 9 | #include "PortableStdint.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #define CHASH_MAXLOOP 5 16 | 17 | typedef int (CHashEqualFunc)(void *, void *); 18 | typedef intptr_t (CHashHashFunc)(void *); 19 | 20 | typedef struct 21 | { 22 | void *k; 23 | void *v; 24 | } CHashRecord; 25 | 26 | typedef struct 27 | { 28 | unsigned char *records; 29 | size_t size; 30 | size_t keyCount; 31 | CHashHashFunc *hash1; 32 | CHashHashFunc *hash2; 33 | CHashEqualFunc *equals; 34 | intptr_t mask; 35 | int isResizing; 36 | } CHash; 37 | 38 | BASEKIT_API CHash *CHash_new(void); 39 | BASEKIT_API void CHash_copy_(CHash *self, const CHash *other); 40 | BASEKIT_API CHash *CHash_clone(CHash *self); 41 | BASEKIT_API void CHash_free(CHash *self); 42 | 43 | BASEKIT_API void CHash_setHash1Func_(CHash *self, CHashHashFunc *f); 44 | BASEKIT_API void CHash_setHash2Func_(CHash *self, CHashHashFunc *f); 45 | BASEKIT_API void CHash_setEqualFunc_(CHash *self, CHashEqualFunc *f); 46 | 47 | BASEKIT_API void CHash_removeKey_(CHash *self, void *k); 48 | BASEKIT_API void CHash_clear(CHash *self); 49 | BASEKIT_API size_t CHash_size(CHash *self); // actually the keyCount 50 | 51 | BASEKIT_API size_t CHash_memorySize(CHash *self); 52 | BASEKIT_API void CHash_compact(CHash *self); 53 | 54 | // private methods ------------------------------- 55 | 56 | BASEKIT_API void CHash_setSize_(CHash *self, size_t size); 57 | BASEKIT_API int CHash_insert_(CHash *self, CHashRecord *x); 58 | BASEKIT_API void CHash_grow(CHash *self); 59 | BASEKIT_API void CHash_shrink(CHash *self); 60 | BASEKIT_API void CHash_show(CHash *self); 61 | BASEKIT_API void CHash_updateMask(CHash *self); 62 | BASEKIT_API float CHash_density(CHash *self); 63 | 64 | #include "CHash_inline.h" 65 | 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | #endif 71 | -------------------------------------------------------------------------------- /source/basekit/source/CHash_inline.h: -------------------------------------------------------------------------------- 1 | //metadoc CHash copyright Steve Dekorte 2009 2 | //metadoc CHash license BSD revised 3 | /*metadoc CHash description 4 | CHash - Cuckoo Hash 5 | keys and values are references (they are not copied or freed) 6 | */ 7 | 8 | #ifdef CHASH_C 9 | #define IO_IN_C_FILE 10 | #endif 11 | #include "Common_inline.h" 12 | #ifdef IO_DECLARE_INLINES 13 | 14 | #define CRecords_recordAt_(records, pos) (CHashRecord *)(records + (pos * sizeof(CHashRecord))) 15 | 16 | IOINLINE CHashRecord *CHash_record1_(CHash *self, void *k) 17 | { 18 | // the ~ | 0x1 before the mask ensures an even pos 19 | size_t pos = self->hash1(k) & self->mask; 20 | //printf("pos1 %i/%i\n", pos, self->size); 21 | return CRecords_recordAt_(self->records, pos); 22 | } 23 | 24 | IOINLINE CHashRecord *CHash_record2_(CHash *self, void *k) 25 | { 26 | // the | 0x1 before the mask ensures an odd pos 27 | size_t pos = self->hash2(k) & self->mask; 28 | //printf("pos2 %i/%i\n", pos, self->size); 29 | return CRecords_recordAt_(self->records, pos); 30 | } 31 | 32 | IOINLINE void *CHash_at_(CHash *self, void *k) 33 | { 34 | CHashRecord *r; 35 | 36 | r = CHash_record1_(self, k); 37 | 38 | if(r->k && self->equals(k, r->k)) 39 | { 40 | return r->v; 41 | } 42 | 43 | r = CHash_record2_(self, k); 44 | 45 | if(r->k && self->equals(k, r->k)) 46 | { 47 | return r->v; 48 | } 49 | 50 | return 0x0; 51 | } 52 | 53 | IOINLINE size_t CHash_count(CHash *self) 54 | { 55 | return self->keyCount; 56 | } 57 | 58 | IOINLINE int CHashKey_hasKey_(CHash *self, void *key) 59 | { 60 | return CHash_at_(self, key) != NULL; 61 | } 62 | 63 | IOINLINE int CHash_at_put_(CHash *self, void *k, void *v) 64 | { 65 | CHashRecord *r; 66 | 67 | r = CHash_record1_(self, k); 68 | 69 | if(!r->k) 70 | { 71 | r->k = k; 72 | r->v = v; 73 | self->keyCount ++; 74 | return 0; 75 | } 76 | 77 | if(k == r->k || self->equals(k, r->k)) 78 | { 79 | r->v = v; 80 | return 0; 81 | } 82 | 83 | r = CHash_record2_(self, k); 84 | 85 | if(!r->k) 86 | { 87 | r->k = k; 88 | r->v = v; 89 | self->keyCount ++; 90 | return 0; 91 | } 92 | 93 | if(k == r->k || self->equals(k, r->k)) 94 | { 95 | r->v = v; 96 | return 0; 97 | } 98 | 99 | 100 | { 101 | CHashRecord x; 102 | x.k = k; 103 | x.v = v; 104 | return CHash_insert_(self, &x); 105 | } 106 | } 107 | 108 | IOINLINE void CHash_shrinkIfNeeded(CHash *self) 109 | { 110 | if(self->keyCount < self->size/5) 111 | { 112 | CHash_shrink(self); 113 | } 114 | } 115 | 116 | IOINLINE void CHashRecord_swapWith_(CHashRecord *self, CHashRecord *other) 117 | { 118 | CHashRecord tmp = *self; 119 | *self = *other; 120 | *other = tmp; 121 | } 122 | 123 | IOINLINE void CHash_clean(CHash *self) 124 | { 125 | memset(self->records, 0, sizeof(CHashRecord) * self->size); 126 | self->keyCount = 0; 127 | } 128 | 129 | // --- enumeration -------------------------------------------------- 130 | 131 | #define CHASH_FOREACH(self, pkey, pvalue, code) \ 132 | {\ 133 | CHash *_self = (self);\ 134 | unsigned char *_records = _self->records;\ 135 | unsigned int _i, _size = _self->size;\ 136 | void *pkey;\ 137 | void *pvalue;\ 138 | \ 139 | for (_i = 0; _i < _size; _i ++)\ 140 | {\ 141 | CHashRecord *_record = CRecords_recordAt_(_records, _i);\ 142 | if (_record->k)\ 143 | {\ 144 | pkey = _record->k;\ 145 | pvalue = _record->v;\ 146 | code;\ 147 | }\ 148 | }\ 149 | } 150 | 151 | #undef IO_IN_C_FILE 152 | #endif 153 | -------------------------------------------------------------------------------- /source/basekit/source/Common_inline.h: -------------------------------------------------------------------------------- 1 | 2 | //metadoc Common copyright Steve Dekorte 2002 3 | //metadoc Common license BSD revised 4 | /*metadoc Common description 5 | You may need to add an entry for your C compiler. 6 | */ 7 | 8 | /* 9 | Trick to get inlining to work with various compilers 10 | Kudos to Daniel A. Koepke 11 | */ 12 | 13 | #undef IO_DECLARE_INLINES 14 | #undef IOINLINE 15 | 16 | /* 17 | #if defined(__cplusplus) 18 | #ifdef IO_IN_C_FILE 19 | #else 20 | #define IO_DECLARE_INLINES 21 | #define IOINLINE extern inline 22 | #endif 23 | #else 24 | */ 25 | 26 | #if defined(__APPLE__) 27 | #include "TargetConditionals.h" 28 | #endif 29 | 30 | #if defined __XCODE__ && (TARGET_ASPEN_SIMULATOR || TARGET_OS_ASPEN) 31 | #define NON_EXTERN_INLINES 32 | #else 33 | #if defined __GNUC__ && __GNUC__ >= 4 34 | //#define NON_EXTERN_INLINES 35 | #endif 36 | #endif 37 | 38 | #ifdef NON_EXTERN_INLINES 39 | 40 | #ifdef IO_IN_C_FILE 41 | // in .c 42 | #define IO_DECLARE_INLINES 43 | #define IOINLINE 44 | #else 45 | // in .h 46 | #define IO_DECLARE_INLINES 47 | #define IOINLINE inline 48 | #endif 49 | 50 | #else 51 | 52 | #ifdef IO_IN_C_FILE 53 | // in .c 54 | #define IO_DECLARE_INLINES 55 | #define IOINLINE inline 56 | #else 57 | // in .h 58 | #define IO_DECLARE_INLINES 59 | #define IOINLINE extern inline 60 | #endif 61 | 62 | #endif 63 | 64 | /* 65 | #endif 66 | */ 67 | -------------------------------------------------------------------------------- /source/basekit/source/Date.h: -------------------------------------------------------------------------------- 1 | //metadoc Date copyright Steve Dekorte 2002 2 | //metadoc Date license BSD revised 3 | 4 | #include "Base.h" 5 | 6 | #ifndef DATE_DEFINED 7 | #define DATE_DEFINED 1 8 | 9 | #include "Common.h" 10 | #include "Duration.h" 11 | #include "PortableGettimeofday.h" 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | typedef struct 19 | { 20 | struct timeval tv; 21 | struct timezone tz; 22 | } Date; 23 | 24 | BASEKIT_API double Date_SecondsFrom1970ToNow(void); 25 | 26 | BASEKIT_API Date *Date_new(void); 27 | BASEKIT_API void Date_copy_(Date *self, const Date *other); 28 | BASEKIT_API void Date_free(Date *self); 29 | BASEKIT_API int Date_compare(const Date *self, const Date *other); 30 | 31 | BASEKIT_API void Date_now(Date *self); 32 | BASEKIT_API void Date_setToLocalTimeZone(Date *self); 33 | BASEKIT_API double Date_Clock(void); 34 | 35 | BASEKIT_API void Date_fromLocalTime_(Date *self, struct tm *t); 36 | BASEKIT_API void Date_fromTime_(Date *self, time_t t); 37 | BASEKIT_API time_t Date_asTime(const Date *self); 38 | 39 | // zone 40 | 41 | BASEKIT_API void Date_setToLocalTimeZone(Date *self); 42 | struct timezone Date_timeZone(const Date *self); 43 | BASEKIT_API void Date_setTimeZone_(Date *self, struct timezone tz); 44 | BASEKIT_API void Date_convertToTimeZone_(Date *self, struct timezone tz); 45 | 46 | // components 47 | 48 | BASEKIT_API void Date_setYear_(Date *self, long y); 49 | BASEKIT_API long Date_year(const Date *self); 50 | 51 | BASEKIT_API void Date_setMonth_(Date *self, int m); 52 | BASEKIT_API int Date_month(const Date *self); 53 | 54 | BASEKIT_API void Date_setDay_(Date *self, int d); 55 | BASEKIT_API int Date_day(const Date *self); 56 | 57 | BASEKIT_API void Date_setHour_(Date *self, int h); 58 | BASEKIT_API int Date_hour(const Date *self); 59 | 60 | BASEKIT_API void Date_setMinute_(Date *self, int m); 61 | BASEKIT_API int Date_minute(const Date *self); 62 | 63 | BASEKIT_API void Date_setSecond_(Date *self, double s); 64 | BASEKIT_API double Date_second(const Date *self); 65 | 66 | BASEKIT_API UArray *Date_asSerialization(Date *self); 67 | BASEKIT_API Date *Date_fromSerialization(Date *self, UArray *serialization); 68 | 69 | BASEKIT_API unsigned char Date_isDaylightSavingsTime(const Date *self); 70 | BASEKIT_API int Date_isLeapYear(const Date *self); 71 | 72 | // seconds 73 | 74 | BASEKIT_API double Date_asSeconds(const Date *self); 75 | BASEKIT_API void Date_fromSeconds_(Date *self, double s); 76 | 77 | BASEKIT_API void Date_addSeconds_(Date *self, double s); 78 | BASEKIT_API double Date_secondsSince_(const Date *self, const Date *other); 79 | 80 | // format 81 | 82 | BASEKIT_API void Date_fromString_format_(Date *self, const char *s, const char *format); 83 | 84 | // durations 85 | 86 | BASEKIT_API Duration *Date_newDurationBySubtractingDate_(const Date *self, const Date *other); 87 | BASEKIT_API void Date_addDuration_(Date *self, const Duration *d); 88 | BASEKIT_API void Date_subtractDuration_(Date *self, const Duration *d); 89 | 90 | BASEKIT_API double Date_secondsSinceNow(const Date *self); 91 | 92 | BASEKIT_API UArray *Date_asString(const Date *self, const char *format); 93 | 94 | #ifdef __cplusplus 95 | } 96 | #endif 97 | #endif 98 | -------------------------------------------------------------------------------- /source/basekit/source/Duration.h: -------------------------------------------------------------------------------- 1 | //metadoc Duration copyright Steve Dekorte 2002 2 | //metadoc Duration license BSD revised 3 | 4 | #ifndef DURATION_DEFINED 5 | #define DURATION_DEFINED 1 6 | 7 | #include "Common.h" 8 | #include "UArray.h" 9 | #include "PortableGettimeofday.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef struct 16 | { 17 | double seconds; 18 | } Duration; 19 | 20 | BASEKIT_API Duration *Duration_new(void); 21 | BASEKIT_API Duration *Duration_newWithSeconds_(double s); 22 | BASEKIT_API Duration *Duration_clone(const Duration *self); 23 | BASEKIT_API void Duration_copy_(Duration *self, const Duration *other); 24 | 25 | BASEKIT_API void Duration_free(Duration *self); 26 | BASEKIT_API int Duration_compare(const Duration *self, const Duration *other); 27 | 28 | // components 29 | 30 | BASEKIT_API int Duration_years(const Duration *self); 31 | BASEKIT_API void Duration_setYears_(Duration *self, double y); 32 | 33 | BASEKIT_API int Duration_days(const Duration *self); 34 | BASEKIT_API void Duration_setDays_(Duration *self, double d); 35 | 36 | BASEKIT_API int Duration_hours(const Duration *self); 37 | BASEKIT_API void Duration_setHours_(Duration *self, double m); 38 | 39 | BASEKIT_API int Duration_minutes(const Duration *self); 40 | BASEKIT_API void Duration_setMinutes_(Duration *self, double m); 41 | 42 | BASEKIT_API double Duration_seconds(const Duration *self); 43 | BASEKIT_API void Duration_setSeconds_(Duration *self, double s); 44 | 45 | // total seconds 46 | 47 | BASEKIT_API double Duration_asSeconds(const Duration *self); 48 | BASEKIT_API void Duration_fromSeconds_(Duration *self, double s); 49 | 50 | // strings 51 | 52 | BASEKIT_API UArray *Duration_asUArrayWithFormat_(const Duration *self, const char *format); 53 | BASEKIT_API void Duration_print(const Duration *self); 54 | 55 | // math 56 | 57 | BASEKIT_API void Duration_add_(Duration *self, const Duration *other); 58 | BASEKIT_API void Duration_subtract_(Duration *self, const Duration *other); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | #endif 64 | -------------------------------------------------------------------------------- /source/basekit/source/DynLib.h: -------------------------------------------------------------------------------- 1 | /* based on DynLib.c contributed by Daniel A. Koepke 2 | * Reorg, Steve Dekorte, 2003-08-30 3 | * See _BSDLicense.txt 4 | */ 5 | 6 | #ifndef DYNLIB_DEFINED 7 | #define DYNLIB_DEFINED 1 8 | 9 | #include "Common.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | typedef void DynLibNoArgFunction(void); 16 | typedef void DynLibOneArgFunction(void *arg); 17 | 18 | typedef struct 19 | { 20 | char *path; 21 | char *initFuncName; 22 | void *initArg; 23 | char *freeFuncName; 24 | void *freeArg; 25 | char *error; 26 | void *handle; 27 | int refCount; 28 | } DynLib; 29 | 30 | BASEKIT_API DynLib *DynLib_new(void); 31 | BASEKIT_API void DynLib_free(DynLib *self); 32 | 33 | BASEKIT_API void DynLib_setPath_(DynLib *self, const char *path); 34 | BASEKIT_API char *DynLib_path(DynLib *self); 35 | 36 | BASEKIT_API void DynLib_setInitFuncName_(DynLib *self, const char *name); 37 | BASEKIT_API char *DynLib_initFuncName(DynLib *self); 38 | BASEKIT_API void DynLib_setInitArg_(DynLib *self, void *arg); 39 | 40 | BASEKIT_API void DynLib_setFreeFuncName_(DynLib *self, const char *name); 41 | BASEKIT_API char *DynLib_freeFuncName(DynLib *self); 42 | BASEKIT_API void DynLib_setFreeArg_(DynLib *self, void *arg); 43 | 44 | BASEKIT_API void DynLib_setError_(DynLib *self, const char *path); 45 | BASEKIT_API char *DynLib_error(DynLib *self); 46 | 47 | BASEKIT_API void DynLib_open(DynLib *self); 48 | BASEKIT_API unsigned char DynLib_isOpen(DynLib *self); 49 | BASEKIT_API void DynLib_close(DynLib *self); 50 | BASEKIT_API void *DynLib_pointerForSymbolName_(DynLib *self, const char *symbolName); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | #endif 56 | -------------------------------------------------------------------------------- /source/basekit/source/Hash_fnv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hash_32 - 32 bit Fowler/Noll/Vo hash code 3 | * 4 | * @(#) $Revision: 1.8 $ 5 | * @(#) $Id: hash_32.c,v 1.8 2003/10/03 20:38:13 chongo Exp $ 6 | * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32.c,v $ 7 | * 8 | *** 9 | * 10 | * Fowler/Noll/Vo hash 11 | * 12 | * The basis of this hash algorithm was taken from an idea sent 13 | * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 | * 15 | * Phong Vo (http://www.research.att.com/info/kpv/) 16 | * Glenn Fowler (http://www.research.att.com/~gsf/) 17 | * 18 | * In a subsequent ballot round: 19 | * 20 | * Landon Curt Noll (http://www.isthe.com/chongo/) 21 | * 22 | * improved on their algorithm. Some people tried this hash 23 | * and found that it worked rather well. In an EMail message 24 | * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 | * 26 | * FNV hashes are designed to be fast while maintaining a low 27 | * collision rate. The FNV speed allows one to quickly hash lots 28 | * of data while maintaining a reasonable collision rate. See: 29 | * 30 | * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 | * 32 | * for more details as well as other forms of the FNV hash. 33 | *** 34 | * 35 | * NOTE: The FNV-0 historic hash is not recommended. One should use 36 | * the FNV-1 hash instead. 37 | * 38 | * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the 39 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 40 | * 41 | * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the 42 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 43 | * 44 | *** 45 | * 46 | * Please do not copyright this code. This code is in the public domain. 47 | * 48 | * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 49 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 50 | * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 51 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 52 | * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 53 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 54 | * PERFORMANCE OF THIS SOFTWARE. 55 | * 56 | * By: 57 | * chongo /\oo/\ 58 | * http://www.isthe.com/chongo/ 59 | * 60 | * Share and Enjoy! :-) 61 | */ 62 | 63 | #include 64 | #include "Hash_fnv.h" 65 | 66 | /* 67 | * 32 bit magic FNV-0 and FNV-1 prime 68 | */ 69 | #define FNV_32_PRIME ((Fnv32_t)0x01000193) 70 | 71 | 72 | /* 73 | * fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer 74 | * 75 | * input: 76 | * buf - start of buffer to hash 77 | * len - length of buffer in octets 78 | * hval - previous hash value or 0 if first call 79 | * 80 | * returns: 81 | * 32 bit hash as a static hash type 82 | * 83 | * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval 84 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 85 | * 86 | * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval 87 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 88 | */ 89 | Fnv32_t 90 | fnv_32_buf(void *buf, size_t len, Fnv32_t hval) 91 | { 92 | unsigned char *bp = (unsigned char *)buf; /* start of buffer */ 93 | unsigned char *be = bp + len; /* beyond end of buffer */ 94 | 95 | /* 96 | * FNV-1 hash each octet in the buffer 97 | */ 98 | while (bp < be) { 99 | 100 | /* multiply by the 32 bit FNV magic prime mod 2^32 */ 101 | #if defined(NO_FNV_GCC_OPTIMIZATION) 102 | hval *= FNV_32_PRIME; 103 | #else 104 | hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 105 | #endif 106 | 107 | /* xor the bottom with the current octet */ 108 | hval ^= (Fnv32_t)*bp++; 109 | } 110 | 111 | /* return our new hash value */ 112 | return hval; 113 | } 114 | 115 | 116 | /* 117 | * fnv_32_str - perform a 32 bit Fowler/Noll/Vo hash on a string 118 | * 119 | * input: 120 | * str - string to hash 121 | * hval - previous hash value or 0 if first call 122 | * 123 | * returns: 124 | * 32 bit hash as a static hash type 125 | * 126 | * NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval 127 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 128 | * 129 | * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval 130 | * argument on the first call to either fnv_32_buf() or fnv_32_str(). 131 | */ 132 | Fnv32_t 133 | fnv_32_str(char *str, Fnv32_t hval) 134 | { 135 | unsigned char *s = (unsigned char *)str; /* unsigned string */ 136 | 137 | /* 138 | * FNV-1 hash each octet in the buffer 139 | */ 140 | while (*s) { 141 | 142 | /* multiply by the 32 bit FNV magic prime mod 2^32 */ 143 | #if defined(NO_FNV_GCC_OPTIMIZATION) 144 | hval *= FNV_32_PRIME; 145 | #else 146 | hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 147 | #endif 148 | 149 | /* xor the bottom with the current octet */ 150 | hval ^= (Fnv32_t)*s++; 151 | } 152 | 153 | /* return our new hash value */ 154 | return hval; 155 | } 156 | -------------------------------------------------------------------------------- /source/basekit/source/Hash_murmur.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // MurmurHash2, by Austin Appleby 3 | 4 | // Note - This code makes a few assumptions about how your machine behaves - 5 | 6 | // 1. We can read a 4-byte value from any address without crashing 7 | // 2. sizeof(int) == 4 8 | 9 | // And it has a few limitations - 10 | 11 | // 1. It will not work incrementally. 12 | // 2. It will not produce the same results on little-endian and big-endian 13 | // machines. 14 | 15 | unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed ) 16 | { 17 | // 'm' and 'r' are mixing constants generated offline. 18 | // They're not really 'magic', they just happen to work well. 19 | 20 | const unsigned int m = 0x5bd1e995; 21 | const int r = 24; 22 | 23 | // Initialize the hash to a 'random' value 24 | 25 | unsigned int h = seed ^ len; 26 | 27 | // Mix 4 bytes at a time into the hash 28 | 29 | const unsigned char * data = (const unsigned char *)key; 30 | 31 | while(len >= 4) 32 | { 33 | unsigned int k = *(unsigned int *)data; 34 | 35 | k *= m; 36 | k ^= k >> r; 37 | k *= m; 38 | 39 | h *= m; 40 | h ^= k; 41 | 42 | data += 4; 43 | len -= 4; 44 | } 45 | 46 | // Handle the last few bytes of the input array 47 | 48 | switch(len) 49 | { 50 | case 3: h ^= data[2] << 16; 51 | case 2: h ^= data[1] << 8; 52 | case 1: h ^= data[0]; 53 | h *= m; 54 | }; 55 | 56 | // Do a few final mixes of the hash to ensure the last few 57 | // bytes are well-incorporated. 58 | 59 | h ^= h >> 13; 60 | h *= m; 61 | h ^= h >> 15; 62 | 63 | return h; 64 | } 65 | -------------------------------------------------------------------------------- /source/basekit/source/Hash_murmur.h: -------------------------------------------------------------------------------- 1 | unsigned int MurmurHash2(const void *key, int len, unsigned int seed); 2 | -------------------------------------------------------------------------------- /source/basekit/source/Hash_superfast.c: -------------------------------------------------------------------------------- 1 | //#include "pstdint.h" /* Replace with if appropriate */ 2 | #include "Common.h" 3 | 4 | #undef get16bits 5 | #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ 6 | || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) 7 | #define get16bits(d) (*((const uint16_t *) (d))) 8 | #endif 9 | 10 | #if !defined (get16bits) 11 | #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ 12 | +(uint32_t)(((const uint8_t *)(d))[0]) ) 13 | #endif 14 | 15 | uint32_t SuperFastHash (const char * data, int len) 16 | { 17 | uint32_t hash = len, tmp; 18 | int rem; 19 | 20 | if (len <= 0 || data == NULL) return 0; 21 | 22 | rem = len & 3; 23 | len >>= 2; 24 | 25 | /* Main loop */ 26 | for (;len > 0; len--) { 27 | hash += get16bits (data); 28 | tmp = (get16bits (data+2) << 11) ^ hash; 29 | hash = (hash << 16) ^ tmp; 30 | data += 2*sizeof (uint16_t); 31 | hash += hash >> 11; 32 | } 33 | 34 | /* Handle end cases */ 35 | switch (rem) { 36 | case 3: hash += get16bits (data); 37 | hash ^= hash << 16; 38 | hash ^= data[sizeof (uint16_t)] << 18; 39 | hash += hash >> 11; 40 | break; 41 | case 2: hash += get16bits (data); 42 | hash ^= hash << 11; 43 | hash += hash >> 17; 44 | break; 45 | case 1: hash += *data; 46 | hash ^= hash << 10; 47 | hash += hash >> 1; 48 | } 49 | 50 | /* Force "avalanching" of final 127 bits */ 51 | hash ^= hash << 3; 52 | hash += hash >> 5; 53 | hash ^= hash << 4; 54 | hash += hash >> 17; 55 | hash ^= hash << 25; 56 | hash += hash >> 6; 57 | 58 | return hash; 59 | } 60 | -------------------------------------------------------------------------------- /source/basekit/source/Hash_superfast.h: -------------------------------------------------------------------------------- 1 | uint32_t SuperFastHash (const char * data, int len); -------------------------------------------------------------------------------- /source/basekit/source/List.h: -------------------------------------------------------------------------------- 1 | //metadoc List copyright Steve Dekorte 2002 2 | //metadoc List license BSD revised 3 | /*metadoc List description 4 | List - an array of void pointers 5 | User is responsible for io_freeing items 6 | */ 7 | 8 | #ifndef LIST_DEFINED 9 | #define LIST_DEFINED 1 10 | 11 | #include "Common.h" 12 | #include "PortableSorting.h" 13 | #include 14 | #include 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | #ifdef LOW_MEMORY_SYSTEM 22 | #define LIST_START_SIZE 1 23 | #define LIST_RESIZE_FACTOR 2 24 | #else 25 | #define LIST_START_SIZE 1 26 | #define LIST_RESIZE_FACTOR 2 27 | #endif 28 | 29 | #define LIST_AT_(self, n) self->items[n] 30 | 31 | 32 | typedef void (ListDoCallback)(void *); 33 | typedef void (ListDoWithCallback)(void *, void *); 34 | typedef void *(ListCollectCallback)(void *); 35 | typedef int (ListSelectCallback)(void *); 36 | typedef int (ListDetectCallback)(void *); 37 | typedef int (ListSortCallback)(const void *, const void *); 38 | typedef int (ListSortRCallback)(void *, const void *, const void *); 39 | typedef int (ListCompareFunc)(const void *, const void *); 40 | 41 | typedef struct 42 | { 43 | void **items; 44 | size_t size; 45 | size_t memSize; 46 | } List; 47 | 48 | typedef struct 49 | { 50 | List *list; 51 | size_t index; 52 | } ListCursor; 53 | 54 | BASEKIT_API List *List_new(void); 55 | BASEKIT_API List *List_clone(const List *self); 56 | BASEKIT_API List *List_cloneSlice(const List *self, long startIndex, long endIndex); 57 | 58 | BASEKIT_API void List_free(List *self); 59 | BASEKIT_API void List_removeAll(List *self); 60 | BASEKIT_API void List_copy_(List *self, const List *otherList); 61 | BASEKIT_API int List_equals_(const List *self, const List *otherList); 62 | BASEKIT_API size_t List_memorySize(const List *self); 63 | 64 | #include "UArray.h" 65 | 66 | BASEKIT_API UArray List_asStackAllocatedUArray(List *self); 67 | 68 | // sizing 69 | 70 | BASEKIT_API void List_preallocateToSize_(List *self, size_t index); 71 | BASEKIT_API void List_setSize_(List *self, size_t index); 72 | BASEKIT_API void List_compact(List *self); 73 | 74 | // utility 75 | 76 | BASEKIT_API void List_print(const List *self); 77 | BASEKIT_API void List_sliceInPlace(List *self, long startIndex, long endIndex); 78 | 79 | // enumeration 80 | 81 | BASEKIT_API void List_do_(List *self, ListDoCallback *callback); 82 | BASEKIT_API void List_do_with_(List *self, ListDoWithCallback *callback, void *arg); 83 | 84 | BASEKIT_API List *List_map_(List *self, ListCollectCallback *callback); 85 | BASEKIT_API void List_mapInPlace_(List *self, ListCollectCallback *callback); 86 | BASEKIT_API void *List_detect_(List *self, ListDetectCallback *callback); 87 | BASEKIT_API List *List_select_(List *self, ListSelectCallback *callback); 88 | 89 | BASEKIT_API void *List_anyOne(const List *self); 90 | BASEKIT_API void List_shuffle(List *self); 91 | BASEKIT_API void *List_removeLast(List *self); 92 | 93 | #include "List_inline.h" 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | #endif 99 | -------------------------------------------------------------------------------- /source/basekit/source/MainArgs.c: -------------------------------------------------------------------------------- 1 | //metadoc MainArgs copyright Steve Dekorte 2002 2 | //metadoc MainArgs license BSD revised 3 | 4 | #include "Base.h" 5 | #include 6 | #include 7 | #include 8 | #include "MainArgs.h" 9 | #include "PortableStrlcpy.h" 10 | 11 | MainArgs *MainArgs_new(void) 12 | { 13 | MainArgs *self = (MainArgs *)io_calloc(1, sizeof(MainArgs)); 14 | return self; 15 | } 16 | 17 | void MainArgs_free(MainArgs *self) 18 | { 19 | if (self->argv) 20 | { 21 | int i; 22 | 23 | for (i = 0; i < self->argc; i ++) 24 | { 25 | io_free((char *)(self->argv[i])); 26 | } 27 | 28 | io_free((void*)(self->argv)); 29 | } 30 | 31 | io_free(self); 32 | } 33 | 34 | void MainArgs_argc_argv_(MainArgs *self, int argc, const char **argv) 35 | { 36 | int i; 37 | 38 | self->argc = argc; 39 | // copy by reference since args should be retained on 40 | // the C stack until the program exits 41 | 42 | self->argv = (const char **)io_calloc(1, sizeof(char *)*argc); 43 | 44 | for (i = 0; i < argc; i ++) 45 | { 46 | const char *s = argv[i]; 47 | size_t len = strlen(s); 48 | char *ptr = (char *)io_calloc(1, len + 1); 49 | PortableStrlcpy(ptr, s, len + 1); 50 | self->argv[i] = ptr; 51 | 52 | //self->argv[i] = strcpy((char *)io_calloc(1, strlen(s)+1), s); 53 | /*printf("argv[%i] = '%s'\n", i, s);*/ 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /source/basekit/source/MainArgs.h: -------------------------------------------------------------------------------- 1 | //metadoc MainArgs copyright Steve Dekorte 2002 2 | //metadoc MainArgs license BSD revised 3 | /*metadoc MainArgs description 4 | Structure for copying and storing command line arguments.") 5 | */ 6 | 7 | #ifndef MAINARGS_DEFINED 8 | #define MAINARGS_DEFINED 1 9 | 10 | #include "Common.h" 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | typedef struct 17 | { 18 | int argc; 19 | const char **argv; 20 | } MainArgs; 21 | 22 | BASEKIT_API MainArgs *MainArgs_new(void); 23 | BASEKIT_API void MainArgs_free(MainArgs *self); 24 | 25 | BASEKIT_API void MainArgs_argc_argv_(MainArgs *self, int argc, const char **argv); 26 | #define MainArgs_argCount(self) self->argc 27 | #define MainArgs_argAt_(self, index) self->argv[index] 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /source/basekit/source/PointerHash.c: -------------------------------------------------------------------------------- 1 | //metadoc PointerHash copyright Steve Dekorte 2002 2 | //metadoc PointerHash license BSD revised 3 | //metadoc PointerHash notes Suggestion to use cuckoo hash and original implementation by Marc Fauconneau 4 | 5 | #define POINTERHASH_C 6 | #include "PointerHash.h" 7 | #undef POINTERHASH_C 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | PointerHash *PointerHash_new(void) 14 | { 15 | PointerHash *self = (PointerHash *)io_calloc(1, sizeof(PointerHash)); 16 | PointerHash_setSize_(self, 8); 17 | return self; 18 | } 19 | 20 | void PointerHash_copy_(PointerHash *self, const PointerHash *other) 21 | { 22 | io_free(self->records); 23 | memcpy(self, other, sizeof(PointerHash)); 24 | self->records = malloc(self->size * sizeof(PointerHashRecord)); 25 | memcpy(self->records, other->records, self->size * sizeof(PointerHashRecord)); 26 | } 27 | 28 | PointerHash *PointerHash_clone(PointerHash *self) 29 | { 30 | PointerHash *other = PointerHash_new(); 31 | PointerHash_copy_(other, self); 32 | return other; 33 | } 34 | 35 | void PointerHash_setSize_(PointerHash *self, size_t size) 36 | { 37 | self->records = realloc(self->records, size * sizeof(PointerHashRecord)); 38 | 39 | if(size > self->size) 40 | { 41 | memset(self->records + self->size * sizeof(PointerHashRecord), 42 | 0x0, (size - self->size) * sizeof(PointerHashRecord)); 43 | } 44 | 45 | self->size = size; 46 | 47 | PointerHash_updateMask(self); 48 | } 49 | 50 | void PointerHash_updateMask(PointerHash *self) 51 | { 52 | self->mask = (intptr_t)(self->size - 1); 53 | } 54 | 55 | void PointerHash_show(PointerHash *self) 56 | { 57 | size_t i; 58 | 59 | printf("PointerHash records:\n"); 60 | for(i = 0; i < self->size; i++) 61 | { 62 | PointerHashRecord *r = PointerHashRecords_recordAt_(self->records, i); 63 | printf(" %i: %p %p\n", (int)i, r->k, r->v); 64 | } 65 | } 66 | 67 | void PointerHash_free(PointerHash *self) 68 | { 69 | io_free(self->records); 70 | io_free(self); 71 | } 72 | 73 | void PointerHash_insert_(PointerHash *self, PointerHashRecord *x) 74 | { 75 | int n; 76 | 77 | for (n = 0; n < POINTERHASH_MAXLOOP; n ++) 78 | { 79 | PointerHashRecord *r; 80 | 81 | r = PointerHash_record1_(self, x->k); 82 | PointerHashRecord_swapWith_(x, r); 83 | if(x->k == 0x0) { self->keyCount ++; return; } 84 | 85 | r = PointerHash_record2_(self, x->k); 86 | PointerHashRecord_swapWith_(x, r); 87 | if(x->k == 0x0) { self->keyCount ++; return; } 88 | } 89 | 90 | PointerHash_grow(self); 91 | PointerHash_at_put_(self, x->k, x->v); 92 | } 93 | 94 | void PointerHash_insertRecords(PointerHash *self, unsigned char *oldRecords, size_t oldSize) 95 | { 96 | size_t i; 97 | 98 | for (i = 0; i < oldSize; i ++) 99 | { 100 | PointerHashRecord *r = PointerHashRecords_recordAt_(oldRecords, i); 101 | 102 | if (r->k) 103 | { 104 | PointerHash_at_put_(self, r->k, r->v); 105 | } 106 | } 107 | } 108 | 109 | void PointerHash_resizeTo_(PointerHash *self, size_t newSize) 110 | { 111 | unsigned char *oldRecords = self->records; 112 | size_t oldSize = self->size; 113 | self->size = newSize; 114 | self->records = io_calloc(1, sizeof(PointerHashRecord) * self->size); 115 | self->keyCount = 0; 116 | PointerHash_updateMask(self); 117 | PointerHash_insertRecords(self, oldRecords, oldSize); 118 | io_free(oldRecords); 119 | } 120 | 121 | void PointerHash_grow(PointerHash *self) 122 | { 123 | PointerHash_resizeTo_(self, self->size * 2); 124 | } 125 | 126 | void PointerHash_shrink(PointerHash *self) 127 | { 128 | PointerHash_resizeTo_(self, self->size / 2); 129 | } 130 | 131 | void PointerHash_removeKey_(PointerHash *self, void *k) 132 | { 133 | PointerHashRecord *r; 134 | 135 | r = PointerHash_record1_(self, k); 136 | if(r->k == k) 137 | { 138 | r->k = 0x0; 139 | r->v = 0x0; 140 | self->keyCount --; 141 | PointerHash_shrinkIfNeeded(self); 142 | return; 143 | } 144 | 145 | r = PointerHash_record2_(self, k); 146 | if(r->k == k) 147 | { 148 | r->k = 0x0; 149 | r->v = 0x0; 150 | self->keyCount --; 151 | PointerHash_shrinkIfNeeded(self); 152 | return; 153 | } 154 | } 155 | 156 | size_t PointerHash_size(PointerHash *self) // actually the keyCount 157 | { 158 | return self->keyCount; 159 | } 160 | 161 | // ---------------------------- 162 | 163 | size_t PointerHash_memorySize(PointerHash *self) 164 | { 165 | return sizeof(PointerHash) + self->size * sizeof(PointerHashRecord); 166 | } 167 | 168 | void PointerHash_compact(PointerHash *self) 169 | { 170 | } 171 | -------------------------------------------------------------------------------- /source/basekit/source/PointerHash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PointerHash.h 3 | * CuckooHashTable 4 | * 5 | * Created by Steve Dekorte on 2009 04 28. 6 | * Copyright 2009 __MyCompanyName__. All rights reserved. 7 | * 8 | */ 9 | 10 | #ifndef POINTERHASH_DEFINED 11 | #define POINTERHASH_DEFINED 1 12 | 13 | #include "Common.h" 14 | #include 15 | #include "PortableStdint.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | #define POINTERHASH_MAXLOOP 10 22 | 23 | #include "PointerHash_struct.h" 24 | 25 | BASEKIT_API PointerHash *PointerHash_new(void); 26 | BASEKIT_API void PointerHash_copy_(PointerHash *self, const PointerHash *other); 27 | BASEKIT_API PointerHash *PointerHash_clone(PointerHash *self); 28 | BASEKIT_API void PointerHash_free(PointerHash *self); 29 | 30 | BASEKIT_API void PointerHash_at_put_(PointerHash *self, void *k, void *v); 31 | BASEKIT_API void PointerHash_removeKey_(PointerHash *self, void *k); 32 | BASEKIT_API size_t PointerHash_size(PointerHash *self); // actually the keyCount 33 | 34 | BASEKIT_API size_t PointerHash_memorySize(PointerHash *self); 35 | BASEKIT_API void PointerHash_compact(PointerHash *self); 36 | 37 | // --- private methods ---------------------------------------- 38 | 39 | BASEKIT_API void PointerHash_setSize_(PointerHash *self, size_t size); 40 | BASEKIT_API void PointerHash_insert_(PointerHash *self, PointerHashRecord *x); 41 | BASEKIT_API void PointerHash_grow(PointerHash *self); 42 | BASEKIT_API void PointerHash_shrinkIfNeeded(PointerHash *self); 43 | BASEKIT_API void PointerHash_shrink(PointerHash *self); 44 | BASEKIT_API void PointerHash_show(PointerHash *self); 45 | BASEKIT_API void PointerHash_updateMask(PointerHash *self); 46 | 47 | #include "PointerHash_inline.h" 48 | 49 | #define PointerHash_cleanSlots(self) 50 | #define PointerHash_hasDirtyKey_(self, k) 0 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | #endif 56 | -------------------------------------------------------------------------------- /source/basekit/source/PointerHash_inline.h: -------------------------------------------------------------------------------- 1 | //metadoc PointerHash copyright Steve Dekorte 2002, Marc Fauconneau 2007 2 | //metadoc PointerHash license BSD revised 3 | /*metadoc PointerHash description 4 | PointerHash - Cuckoo Hash 5 | keys and values are references (they are not copied or freed) 6 | key pointers are assumed unique 7 | */ 8 | 9 | #ifdef POINTERHASH_C 10 | #define IO_IN_C_FILE 11 | #endif 12 | #include "Common_inline.h" 13 | #ifdef IO_DECLARE_INLINES 14 | 15 | #define PointerHashRecords_recordAt_(records, pos) (PointerHashRecord *)(records + (pos * sizeof(PointerHashRecord))) 16 | 17 | /* 18 | IOINLINE unsigned int PointerHash_hash(PointerHash *self, void *key) 19 | { 20 | intptr_t k = (intptr_t)PointerHashKey_value(key); 21 | return k^(k>>4); 22 | } 23 | 24 | IOINLINE unsigned int PointerHash_hash_more(PointerHash *self, unsigned int hash) 25 | { 26 | return hash ^ (hash >> self->log2tableSize); 27 | } 28 | */ 29 | 30 | // ----------------------------------- 31 | 32 | IOINLINE PointerHashRecord *PointerHash_record1_(PointerHash *self, void *k) 33 | { 34 | // the ~| 0x1 before the mask ensures an odd pos 35 | intptr_t kk = (intptr_t)k; 36 | size_t pos = ((kk^(kk>>4)) | 0x1) & self->mask; 37 | return PointerHashRecords_recordAt_(self->records, pos); 38 | } 39 | 40 | IOINLINE PointerHashRecord *PointerHash_record2_(PointerHash *self, void *k) 41 | { 42 | // the | 0x1 before the mask ensures an even pos 43 | intptr_t kk = (intptr_t)k; 44 | //size_t pos = (((kk^(kk/33)) << 1)) & self->mask; 45 | size_t pos = (kk << 1) & self->mask; 46 | return PointerHashRecords_recordAt_(self->records, pos); 47 | } 48 | 49 | IOINLINE void *PointerHash_at_(PointerHash *self, void *k) 50 | { 51 | PointerHashRecord *r; 52 | 53 | r = PointerHash_record1_(self, k); 54 | if(k == r->k) return r->v; 55 | 56 | r = PointerHash_record2_(self, k); 57 | if(k == r->k) return r->v; 58 | 59 | return 0x0; 60 | } 61 | 62 | IOINLINE size_t PointerHash_count(PointerHash *self) 63 | { 64 | return self->keyCount; 65 | } 66 | 67 | IOINLINE int PointerHashKey_hasKey_(PointerHash *self, void *key) 68 | { 69 | return PointerHash_at_(self, key) != NULL; 70 | } 71 | 72 | IOINLINE void PointerHash_at_put_(PointerHash *self, void *k, void *v) 73 | { 74 | PointerHashRecord *r; 75 | 76 | r = PointerHash_record1_(self, k); 77 | 78 | if(!r->k) 79 | { 80 | r->k = k; 81 | r->v = v; 82 | self->keyCount ++; 83 | return; 84 | } 85 | 86 | if(r->k == k) 87 | { 88 | r->v = v; 89 | return; 90 | } 91 | 92 | r = PointerHash_record2_(self, k); 93 | 94 | if(!r->k) 95 | { 96 | r->k = k; 97 | r->v = v; 98 | self->keyCount ++; 99 | return; 100 | } 101 | 102 | if(r->k == k) 103 | { 104 | r->v = v; 105 | return; 106 | } 107 | 108 | { 109 | PointerHashRecord x; 110 | x.k = k; 111 | x.v = v; 112 | PointerHash_insert_(self, &x); 113 | } 114 | } 115 | 116 | IOINLINE void PointerHash_shrinkIfNeeded(PointerHash *self) 117 | { 118 | if(self->keyCount < self->size/8) 119 | { 120 | PointerHash_shrink(self); 121 | } 122 | } 123 | 124 | IOINLINE void PointerHashRecord_swapWith_(PointerHashRecord *self, PointerHashRecord *other) 125 | { 126 | PointerHashRecord tmp = *self; 127 | *self = *other; 128 | *other = tmp; 129 | } 130 | 131 | IOINLINE void PointerHash_clean(PointerHash *self) 132 | { 133 | memset(self->records, 0, sizeof(PointerHashRecord) * self->size); 134 | self->keyCount = 0; 135 | } 136 | 137 | // --- enumeration -------------------------------------------------- 138 | 139 | #define POINTERHASH_FOREACH(self, pkey, pvalue, code) \ 140 | {\ 141 | PointerHash *_self = (self);\ 142 | unsigned char *_records = _self->records;\ 143 | unsigned int _i, _size = _self->size;\ 144 | void *pkey;\ 145 | void *pvalue;\ 146 | \ 147 | for (_i = 0; _i < _size; _i ++)\ 148 | {\ 149 | PointerHashRecord *_record = PointerHashRecords_recordAt_(_records, _i);\ 150 | if (_record->k)\ 151 | {\ 152 | pkey = _record->k;\ 153 | pvalue = _record->v;\ 154 | code;\ 155 | }\ 156 | }\ 157 | } 158 | 159 | #undef IO_IN_C_FILE 160 | #endif 161 | -------------------------------------------------------------------------------- /source/basekit/source/PointerHash_struct.h: -------------------------------------------------------------------------------- 1 | // PointerHash.h 2 | // CuckooHashTable 3 | // Created by Steve Dekorte on 2009 04 28. 4 | 5 | #ifndef POINTERHASH_STRUCT_DEFINED 6 | #define POINTERHASH_STRUCT_DEFINED 1 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct 13 | { 14 | void *k; 15 | void *v; 16 | } PointerHashRecord; 17 | 18 | typedef struct 19 | { 20 | unsigned char *records; 21 | size_t size; 22 | size_t keyCount; 23 | intptr_t mask; 24 | } PointerHash; 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | #endif 30 | -------------------------------------------------------------------------------- /source/basekit/source/PortableGettimeofday.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "PortableGettimeofday.h" 5 | 6 | #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) 7 | 8 | #if defined(__MINGW32__) && (3 < __MINGW32_MAJOR_VERSION || 3 == __MINGW32_MAJOR_VERSION && 9 < __MINGW32_MINOR_VERSION) 9 | #else 10 | 11 | #ifndef IO_ADDON_Sockets 12 | void gettimeofday(struct timeval *tv, struct timezone *tz) 13 | { 14 | TIME_ZONE_INFORMATION zoneInfo; 15 | 16 | struct _timeb timeb; 17 | _ftime_s(&timeb); 18 | 19 | tv->tv_sec = (long) timeb.time; 20 | tv->tv_usec = (long) (timeb.millitm * 1000); 21 | 22 | if (GetTimeZoneInformation(&zoneInfo) != TIME_ZONE_ID_INVALID) 23 | { 24 | tz->tz_minuteswest = zoneInfo.Bias; 25 | tz->tz_dsttime = 0; 26 | } 27 | else 28 | { 29 | tz->tz_minuteswest = 0; 30 | tz->tz_dsttime = 0; 31 | } 32 | } 33 | #endif 34 | #endif 35 | #else 36 | 37 | /* just to make compiler happy */ 38 | void PortableGettimeOfday(void) 39 | { 40 | } 41 | 42 | #endif 43 | 44 | double secondsSince1970(void) 45 | { 46 | double result; 47 | struct timeval tv; 48 | struct timezone tz; 49 | gettimeofday(&tv, &tz); 50 | result = tv.tv_sec; 51 | result += tv.tv_usec / 1000000.0; 52 | return result; 53 | } 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /source/basekit/source/PortableGettimeofday.h: -------------------------------------------------------------------------------- 1 | #ifndef PORTABLEGETTIMEOFDAY_DEFINED 2 | #define PORTABLEGETTIMEOFDAY_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) 9 | #if defined(_MSC_VER) 10 | #include 11 | /*struct timeval 12 | { 13 | long tv_sec; 14 | long tv_usec; 15 | };*/ 16 | #else 17 | /* for MingW */ 18 | #include 19 | #endif 20 | 21 | #if defined(__MINGW32__) && (3 < __MINGW32_MAJOR_VERSION || 3 == __MINGW32_MAJOR_VERSION && 9 < __MINGW32_MINOR_VERSION) 22 | #else 23 | struct timezone 24 | { 25 | int tz_minuteswest; /* of Greenwich */ 26 | int tz_dsttime; /* type of dst correction to apply */ 27 | }; 28 | 29 | #include "Common.h" 30 | BASEKIT_API extern void gettimeofday(struct timeval *tv, struct timezone *tz); 31 | #endif 32 | 33 | #else 34 | #include 35 | #endif 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif 42 | 43 | double secondsSince1970(void); 44 | -------------------------------------------------------------------------------- /source/basekit/source/PortableSorting.c: -------------------------------------------------------------------------------- 1 | #include "PortableSorting.h" 2 | 3 | typedef struct 4 | { 5 | void *base; 6 | size_t size; 7 | size_t width; 8 | void *context; 9 | PortableSortingCompareCallback compare; 10 | unsigned char *swapSpace; 11 | } Sorter; 12 | 13 | void Sorter_quickSort(Sorter *self, size_t lb, size_t ub); 14 | size_t Sorter_quickSortRearrange(Sorter *self, size_t lb, size_t ub); 15 | 16 | void portable_qsort_r(void *base, size_t size, size_t width, 17 | void *context, PortableSortingCompareCallback compare) 18 | { 19 | if (size > 0 && width > 0) 20 | { 21 | Sorter s; 22 | s.base = base; 23 | s.size = size; 24 | s.width = width; 25 | s.context = context; 26 | s.compare = compare; 27 | s.swapSpace = malloc(width); 28 | Sorter_quickSort(&s, 0, size-1); 29 | free(s.swapSpace); 30 | } 31 | } 32 | 33 | void Sorter_quickSort(Sorter *self, size_t lb, size_t ub) 34 | { 35 | if (lb < ub) 36 | { 37 | size_t j = Sorter_quickSortRearrange(self, lb, ub); 38 | 39 | if (j) 40 | { 41 | Sorter_quickSort(self, lb, j - 1); 42 | } 43 | 44 | Sorter_quickSort(self, j + 1, ub); 45 | } 46 | } 47 | 48 | static void swap(void *base, size_t a, size_t b, size_t width, unsigned char *swapSpace) 49 | { 50 | //unsigned char swapSpace[width]; // windows can't deal with this 51 | void *ap = ((unsigned char *)base) + width*a; 52 | void *bp = ((unsigned char *)base) + width*b; 53 | memcpy(swapSpace, ap, width); 54 | memcpy(ap, bp, width); 55 | memcpy(bp, swapSpace, width); 56 | } 57 | 58 | size_t Sorter_quickSortRearrange(Sorter *self, size_t lb, size_t ub) 59 | { 60 | PortableSortingCompareCallback comp = self->compare; 61 | void *context = self->context; 62 | unsigned char *base = self->base; 63 | size_t width = self->width; 64 | 65 | do { 66 | while (ub > lb && (*comp)(context, base + width*ub, base + width*lb) >= 0) 67 | { 68 | ub --; 69 | } 70 | 71 | if (ub != lb) 72 | { 73 | swap(base, ub, lb, width, self->swapSpace); 74 | 75 | while (lb < ub && (*comp)(context, base + width*lb, base + width*ub) <= 0) 76 | { 77 | lb ++; 78 | } 79 | 80 | if (lb != ub) 81 | { 82 | swap(base, lb, ub, width, self->swapSpace); 83 | } 84 | } 85 | } while (lb != ub); 86 | 87 | return lb; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /source/basekit/source/PortableSorting.h: -------------------------------------------------------------------------------- 1 | #ifndef PORTABLESORTING_DEFINED 2 | #define PORTABLESORTING_DEFINED 1 3 | 4 | #include "Common.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* 11 | The reason for using this instead of C's qsort is 12 | that we need more context information than just the 13 | two objects if we want to do something like use an 14 | Io block to do the comparison and using globals is 15 | unacceptable for several reasons. 16 | 17 | qsort_r isn't available on all platforms. 18 | */ 19 | 20 | //typedef int (ListSortRCallback)(void *, const void *, const void *); 21 | 22 | typedef int (*PortableSortingCompareCallback)(void *context, const void *a, const void *b); 23 | 24 | BASEKIT_API void portable_qsort_r(void *base, size_t nel, size_t width, 25 | void *context, PortableSortingCompareCallback compare); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /source/basekit/source/PortableStrlcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998 Todd C. Miller 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 18 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 19 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include 29 | #include "PortableStrlcpy.h" 30 | 31 | /* 32 | * Copy src to string dest of size len. At most len-1 characters 33 | * will be copied. Always NUL terminates (unless len == 0). 34 | * Returns strlen(src); if retval >= len, truncation occurred. 35 | */ 36 | size_t PortableStrlcpy(char* dest, const char* src, size_t len) 37 | { 38 | char* d = dest; 39 | const char* s = src; 40 | size_t n = len; 41 | 42 | /* Copy as many bytes as will fit */ 43 | if (n != 0 && --n != 0) 44 | { 45 | do 46 | { 47 | if ((*d++ = *s++) == 0) 48 | break; 49 | } while (--n != 0); 50 | } 51 | 52 | /* Not enough room in dest, add NUL and traverse rest of src */ 53 | if (n == 0) 54 | { 55 | if (len != 0) 56 | *d = '\0'; /* NUL-terminate dest */ 57 | while (*s++); 58 | } 59 | 60 | return (s - src - 1); /* count doesn't include NUL */ 61 | } 62 | -------------------------------------------------------------------------------- /source/basekit/source/PortableStrlcpy.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include // size_t on windows 3 | #else 4 | #include // size_t 5 | #endif 6 | 7 | #define strlcpy(d, s, l) PortableStrlcpy((d), (s), (l)) 8 | 9 | size_t PortableStrlcpy(char*, const char*, size_t); 10 | -------------------------------------------------------------------------------- /source/basekit/source/PortableStrptime.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | /*#ifdef IO_NEEDS_STRPTIME */ 8 | char *io_strptime(char *buf, char *fmt, struct tm *tm); 9 | /*#endif*/ 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /source/basekit/source/PortableTruncate.c: -------------------------------------------------------------------------------- 1 | 2 | #include "PortableTruncate.h" 3 | 4 | 5 | int PortableTruncate_justHereToAvoidRanlibWarning(void) { return 0; } 6 | 7 | #ifdef _WIN32 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // Win32 truncate by Mike Austin 15 | 16 | int truncate(const char *path, long length) 17 | { 18 | HANDLE file = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 19 | FILE_SHARE_WRITE | FILE_SHARE_READ, NULL); 20 | 21 | if (file == INVALID_HANDLE_VALUE) 22 | { 23 | return -1; 24 | } 25 | 26 | if (SetFilePointer(file, length, NULL, FILE_BEGIN) == 0xFFFFFFFF || !SetEndOfFile(file)) 27 | { 28 | CloseHandle(file); 29 | return -1; 30 | } 31 | 32 | CloseHandle(file); 33 | return 0; 34 | } 35 | 36 | #endif 37 | 38 | #if defined(__SYMBIAN32__) 39 | int truncate(const char* path, long length) 40 | { 41 | // TODO: Implement for Symbian 42 | return -1; 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /source/basekit/source/PortableTruncate.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | 6 | 7 | #ifdef _WIN32 8 | #include "Common.h" 9 | 10 | BASEKIT_API int truncate(const char *path, long length); 11 | 12 | #else 13 | 14 | #include 15 | 16 | #endif 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /source/basekit/source/PortableUsleep.c: -------------------------------------------------------------------------------- 1 | int PortableUsleep_justHereToAvoidRanlibWarning(void) { return 0; } 2 | 3 | #ifdef WIN32 4 | #include 5 | 6 | int usleep(unsigned int us) 7 | { 8 | static LARGE_INTEGER freq; 9 | static int initted = 0; 10 | LARGE_INTEGER s, e, d; 11 | 12 | if (!initted) 13 | { 14 | QueryPerformanceFrequency(&freq); 15 | initted = 1; 16 | } 17 | 18 | QueryPerformanceCounter(&s); 19 | d.QuadPart = freq.QuadPart * ((double)us / 1000000.0); 20 | 21 | do 22 | { 23 | QueryPerformanceCounter(&e); 24 | } while (e.QuadPart - s.QuadPart < d.QuadPart); 25 | 26 | return 0; 27 | 28 | } 29 | 30 | #endif 31 | 32 | 33 | -------------------------------------------------------------------------------- /source/basekit/source/PortableUsleep.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef ON_WINDOWS 3 | #include 4 | #ifndef WIN32 5 | int usleep (unsigned int us); 6 | #endif 7 | #elif !defined(__CYGWIN__) 8 | #include 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /source/basekit/source/RandomGen.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef RANDOMGEN_DEFINED 4 | #define RANDOMGEN_DEFINED 1 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #include "Common.h" 11 | 12 | #define RANDOMGEN_N 624 13 | 14 | typedef struct 15 | { 16 | unsigned long mt[RANDOMGEN_N]; // the array for the state vector 17 | int mti; // mti==N+1 means mt[N] is not initialized 18 | double y2; // guassian 19 | int use_last; // guassian 20 | } RandomGen; 21 | 22 | BASEKIT_API RandomGen *RandomGen_new(void); 23 | BASEKIT_API void RandomGen_free(RandomGen *self); 24 | 25 | BASEKIT_API void RandomGen_setSeed(RandomGen *self, unsigned long seed); 26 | BASEKIT_API void RandomGen_chooseRandomSeed(RandomGen *self); 27 | 28 | // generates a random number on between 0.0 and 1.0 29 | BASEKIT_API double RandomGen_randomDouble(RandomGen *self); 30 | 31 | BASEKIT_API int RandomGen_randomInt(RandomGen *self); 32 | 33 | BASEKIT_API double RandomGen_gaussian(RandomGen *self, double mean, double standardDeviation); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | #endif 39 | -------------------------------------------------------------------------------- /source/basekit/source/Stack.c: -------------------------------------------------------------------------------- 1 | //metadoc Stack copyright Steve Dekorte 2002 2 | //metadoc Stack license BSD revised 3 | /*metadoc Stack description 4 | Notes: first element of items is always 0x0. 5 | */ 6 | 7 | #define STACK_C 8 | #include "Stack.h" 9 | #undef STACK_C 10 | #if !defined(_MSC_VER) 11 | #include 12 | #endif 13 | 14 | Stack *Stack_new(void) 15 | { 16 | // size is the number of pointers, including the starting NULL. 17 | int size = STACK_START_SIZE; 18 | Stack *self = (Stack *)io_calloc(1, sizeof(Stack)); 19 | self->items = (void **)io_calloc(1, size*sizeof(void *)); 20 | // memEnd points past the end of the items memory block. 21 | self->memEnd = self->items + size; 22 | self->top = self->items; 23 | //self->lastMark = self->items; 24 | return self; 25 | } 26 | 27 | void Stack_free(Stack *self) 28 | { 29 | io_free(self->items); 30 | io_free(self); 31 | } 32 | 33 | Stack *Stack_clone(const Stack *self) 34 | { 35 | Stack *s = (Stack *)cpalloc(self, sizeof(Stack)); 36 | 37 | ptrdiff_t nItems = self->top - self->items; 38 | ptrdiff_t size = nItems + 1; 39 | 40 | s->items = (void **)cpalloc(self->items, size*sizeof(void *)); 41 | s->memEnd = s->items + size; 42 | s->top = s->items + nItems; 43 | return s; 44 | } 45 | 46 | void Stack_copy_(Stack *self, const Stack *other) 47 | { 48 | ptrdiff_t nItems = self->top - self->items; 49 | ptrdiff_t size = nItems + 1; 50 | ptrdiff_t sizeInBytes = size*sizeof(void *); 51 | 52 | self->items = (void **)io_realloc(self->items, sizeInBytes); 53 | memcpy(self->items, other->items, sizeInBytes); 54 | self->memEnd = self->items + size; 55 | self->top = self->items + nItems; 56 | } 57 | 58 | 59 | // stack -------------------------------------------------- 60 | 61 | size_t Stack_memorySize(const Stack *self) 62 | { 63 | return sizeof(Stack) + (self->memEnd - self->items); 64 | } 65 | 66 | void Stack_compact(Stack *self) 67 | { 68 | int oldSize = (1 + self->top - self->items)*sizeof(void *); 69 | self->items = (void **)io_realloc(self->items, oldSize); 70 | } 71 | 72 | void Stack_resize(Stack *self) 73 | { 74 | int oldSize = (self->memEnd - self->items)*sizeof(void *); 75 | int newSize = oldSize*STACK_RESIZE_FACTOR; 76 | int i = self->top - self->items; 77 | self->items = (void **)io_realloc(self->items, newSize); 78 | self->top = self->items + i; 79 | self->memEnd = self->items + (newSize/sizeof(void *)); 80 | } 81 | 82 | // sizing ------------------------------------------------ 83 | 84 | void Stack_do_on_(const Stack *self, StackDoOnCallback *callback, void *target) 85 | { 86 | Stack *stack = Stack_newCopyWithNullMarks(self); 87 | int i; 88 | 89 | for(i = 0; i < Stack_count(stack) - 1; i ++) 90 | { 91 | void *v = Stack_at_(stack, i); 92 | if (v) (*callback)(target, v); 93 | } 94 | 95 | Stack_free(stack); 96 | } 97 | 98 | void Stack_makeMarksNull(Stack *self) 99 | { 100 | ptrdiff_t mark = self->lastMark; 101 | 102 | while (mark) 103 | { 104 | ptrdiff_t nextMark = (ptrdiff_t)self->items[mark]; 105 | self->items[mark] = NULL; 106 | mark = nextMark; 107 | } 108 | } 109 | 110 | Stack *Stack_newCopyWithNullMarks(const Stack *self) 111 | { 112 | Stack *newStack = Stack_clone(self); 113 | Stack_makeMarksNull(newStack); 114 | return newStack; 115 | } 116 | 117 | void Stack_popToMark_(Stack *self, intptr_t mark) 118 | { 119 | while (self->lastMark && self->lastMark != mark) 120 | { 121 | Stack_popMark(self); 122 | } 123 | 124 | if (self->lastMark == 0) 125 | { 126 | printf("Stack error: unable to find mark %p in %p\n", (void *)mark, (void *)self); 127 | exit(1); 128 | } 129 | 130 | Stack_popMark(self); 131 | } 132 | 133 | List *Stack_asList(const Stack *self) // slow 134 | { 135 | List *list = List_new(); 136 | Stack_do_on_(self, (StackDoOnCallback *)List_append_, list); 137 | return list; 138 | } 139 | -------------------------------------------------------------------------------- /source/basekit/source/Stack.h: -------------------------------------------------------------------------------- 1 | //metadoc Stack copyright Steve Dekorte 2002 2 | //metadoc Stack license BSD revised 3 | /*metadoc Stack description 4 | Stack - array of void pointers 5 | supports setting marks - when a mark is popped, 6 | all stack items above it are popped as well 7 | 8 | Designed to optimize push, pushMark and popMark 9 | at the expense of pop (since pop requires a mark check) 10 | */ 11 | 12 | #ifndef STACK_DEFINED 13 | #define STACK_DEFINED 1 14 | 15 | #include "Common.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "List.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | #ifdef LOW_MEMORY_SYSTEM 27 | #define STACK_START_SIZE 512 28 | #define STACK_RESIZE_FACTOR 2 29 | #else 30 | #define STACK_START_SIZE 512 31 | #define STACK_RESIZE_FACTOR 2 32 | #endif 33 | 34 | typedef void (StackDoCallback)(void *); 35 | typedef void (StackDoOnCallback)(void *, void *); 36 | 37 | //#define STACK_POP_CALLBACK 38 | 39 | #ifdef STACK_POP_CALLBACK 40 | typedef void (StackPopCallback)(void *); 41 | #endif 42 | 43 | typedef struct 44 | { 45 | void **items; 46 | void **memEnd; 47 | void **top; 48 | intptr_t lastMark; 49 | 50 | #ifdef STACK_POP_CALLBACK 51 | StackPopCallback *popCallback; 52 | #endif 53 | } Stack; 54 | 55 | #define Stack_popCallback_(self, callback) self->popCallback = callback; 56 | 57 | BASEKIT_API Stack *Stack_new(void); 58 | BASEKIT_API void Stack_free(Stack *self); 59 | BASEKIT_API Stack *Stack_clone(const Stack *self); 60 | BASEKIT_API void Stack_copy_(Stack *self, const Stack *other); 61 | 62 | BASEKIT_API size_t Stack_memorySize(const Stack *self); 63 | BASEKIT_API void Stack_compact(Stack *self); 64 | 65 | BASEKIT_API void Stack_resize(Stack *self); 66 | 67 | BASEKIT_API void Stack_popToMark_(Stack *self, intptr_t mark); 68 | 69 | // not high performance 70 | 71 | BASEKIT_API void Stack_makeMarksNull(Stack *self); 72 | BASEKIT_API Stack *Stack_newCopyWithNullMarks(const Stack *self); 73 | BASEKIT_API void Stack_do_on_(const Stack *self, StackDoOnCallback *callback, void *target); 74 | 75 | BASEKIT_API List *Stack_asList(const Stack *self); 76 | 77 | #include "Stack_inline.h" 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | #endif 83 | -------------------------------------------------------------------------------- /source/basekit/source/Stack_inline.h: -------------------------------------------------------------------------------- 1 | //metadoc Stack copyright Steve Dekorte 2002 2 | //metadoc Stack license BSD revised 3 | /*metadoc Stack description 4 | Stack - array of void pointers 5 | supports setting marks - when a mark is popped, 6 | all stack items above it are popped as well 7 | */ 8 | 9 | #ifdef STACK_C 10 | #define IO_IN_C_FILE 11 | #endif 12 | #include "Common_inline.h" 13 | #ifdef IO_DECLARE_INLINES 14 | 15 | IOINLINE void Stack_do_(const Stack *self, StackDoCallback *callback) 16 | { 17 | void **itemP = self->top; 18 | intptr_t mark = self->lastMark; 19 | 20 | while (itemP > self->items) 21 | { 22 | if (itemP - self->items == mark) 23 | { 24 | mark = (intptr_t)(*itemP); 25 | } 26 | else 27 | { 28 | (*callback)(*itemP); 29 | } 30 | 31 | itemP --; 32 | } 33 | } 34 | 35 | IOINLINE void Stack_doUntilMark_(const Stack *self, StackDoCallback *callback) 36 | { 37 | void **itemP = self->top; 38 | intptr_t mark = self->lastMark; 39 | 40 | while (itemP > self->items) 41 | { 42 | if (itemP - self->items == mark) 43 | { 44 | return; 45 | } 46 | else 47 | { 48 | (*callback)(*itemP); 49 | } 50 | 51 | itemP --; 52 | } 53 | } 54 | 55 | IOINLINE void Stack_clear(Stack *self) 56 | { 57 | self->top = self->items; 58 | self->lastMark = 0; 59 | } 60 | 61 | IOINLINE size_t Stack_totalSize(const Stack *self) 62 | { 63 | return (self->top - self->items); 64 | } 65 | 66 | IOINLINE int Stack_count(const Stack *self) 67 | { 68 | return (self->top - self->items); 69 | } 70 | 71 | IOINLINE void Stack_push_(Stack *self, void *item) 72 | { 73 | self->top ++; 74 | 75 | if (self->top == self->memEnd) 76 | { 77 | Stack_resize(self); 78 | } 79 | 80 | *(self->top) = item; 81 | } 82 | 83 | IOINLINE void Stack_pushMark(Stack *self) 84 | { 85 | Stack_push_(self, (void *)self->lastMark); 86 | self->lastMark = self->top - self->items; 87 | } 88 | 89 | IOINLINE intptr_t Stack_pushMarkPoint(Stack *self) 90 | { 91 | Stack_push_(self, (void *)self->lastMark); 92 | self->lastMark = self->top - self->items; 93 | return self->lastMark; 94 | } 95 | 96 | IOINLINE void *Stack_pop(Stack *self) 97 | { 98 | void *top = *(self->top); 99 | 100 | if (self->items != self->top) 101 | { 102 | #ifdef STACK_POP_CALLBACK 103 | if(self->popCallback) self->popCallback(*(self->top)); 104 | #endif 105 | self->top --; 106 | } 107 | 108 | return top; 109 | } 110 | 111 | IOINLINE void Stack_popMark(Stack *self) 112 | { 113 | #ifdef STACK_POP_CALLBACK 114 | if(self->popCallback) Stack_doUntilMark_(self, self->popCallback); 115 | #endif 116 | 117 | self->top = self->items + self->lastMark - 1; 118 | 119 | if (self->lastMark) 120 | { 121 | self->lastMark = (intptr_t)(self->items[self->lastMark]); 122 | } 123 | } 124 | 125 | IOINLINE int Stack_popMarkPoint_(Stack *self, intptr_t mark) 126 | { 127 | while (self->lastMark && self->lastMark != mark) 128 | { 129 | Stack_popMark(self); 130 | } 131 | 132 | if (self->lastMark != mark) 133 | { 134 | return 0; 135 | } 136 | 137 | Stack_popMark(self); 138 | return 1; 139 | } 140 | 141 | IOINLINE void Stack_clearTop(Stack *self) 142 | { 143 | Stack_popMark(self); 144 | Stack_pushMark(self); 145 | //self->top = self->items + self->lastMark; 146 | } 147 | 148 | IOINLINE void *Stack_top(const Stack *self) 149 | { 150 | return *(self->top); 151 | } 152 | 153 | IOINLINE void *Stack_at_(const Stack *self, int i) 154 | { 155 | return self->items[i + 1]; 156 | } 157 | 158 | 159 | 160 | #undef IO_IN_C_FILE 161 | #endif 162 | 163 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_character.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | 10 | // set 11 | 12 | #define UARRAY_IOP(OP) \ 13 | void UArray_ ## OP (UArray *self) { UARRAY_FOREACHASSIGN(self, i, v, OP((int)v)); } 14 | 15 | UARRAY_IOP(isalnum); 16 | UARRAY_IOP(isalpha); 17 | UARRAY_IOP(iscntrl); 18 | UARRAY_IOP(isdigit); 19 | UARRAY_IOP(isgraph); 20 | UARRAY_IOP(islower); 21 | UARRAY_IOP(isprint); 22 | UARRAY_IOP(ispunct); 23 | UARRAY_IOP(isspace); 24 | UARRAY_IOP(isupper); 25 | UARRAY_IOP(isxdigit); 26 | 27 | UARRAY_IOP(tolower); 28 | UARRAY_IOP(toupper); 29 | 30 | BASEKIT_API int UArray_isLowercase(UArray *self) 31 | { 32 | UARRAY_INTFOREACH(self, i, v, if(v != tolower(v)) return 0); 33 | return 1; 34 | } 35 | 36 | BASEKIT_API int UArray_isUppercase(UArray *self) 37 | { 38 | UARRAY_INTFOREACH(self, i, v, if(v != toupper(v)) return 0); 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_character.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | BASEKIT_API void UArray_isalnum(UArray *self); 7 | BASEKIT_API void UArray_isalpha(UArray *self); 8 | BASEKIT_API void UArray_iscntrl(UArray *self); 9 | BASEKIT_API void UArray_isdigit(UArray *self); 10 | BASEKIT_API void UArray_isgraph(UArray *self); 11 | BASEKIT_API void UArray_islower(UArray *self); 12 | BASEKIT_API void UArray_isprint(UArray *self); 13 | BASEKIT_API void UArray_ispunct(UArray *self); 14 | BASEKIT_API void UArray_isspace(UArray *self); 15 | BASEKIT_API void UArray_isupper(UArray *self); 16 | BASEKIT_API void UArray_isxdigit(UArray *self); 17 | BASEKIT_API void UArray_tolower(UArray *self); 18 | BASEKIT_API void UArray_toupper(UArray *self); 19 | 20 | BASEKIT_API int UArray_isLowercase(UArray *self); 21 | BASEKIT_API int UArray_isUppercase(UArray *self); 22 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_format.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | UArray *UArray_newWithFormat_(const char *format, ...) 13 | { 14 | UArray *self; 15 | va_list ap; 16 | va_start(ap, format); 17 | self = UArray_newWithVargs_(format, ap); 18 | va_end(ap); 19 | return self; 20 | } 21 | 22 | UArray *UArray_newWithVargs_(const char *format, va_list ap) 23 | { 24 | UArray *self = UArray_new(); 25 | UArray_fromVargs_(self, format,ap); 26 | return self; 27 | } 28 | 29 | UArray *UArray_fromFormat_(UArray *self, const char *format, ...) 30 | { 31 | va_list ap; 32 | va_start(ap, format); 33 | UArray_fromVargs_(self, format, ap); 34 | va_end(ap); 35 | return self; 36 | } 37 | 38 | void UArray_fromVargs_(UArray *self, const char *format, va_list ap) 39 | { 40 | while (*format) 41 | { 42 | if (*format == '%') 43 | { 44 | format ++; 45 | 46 | if (*format == 's') 47 | { 48 | char *s = va_arg(ap, char *); 49 | if (!s) { printf("UArray_fromVargs_ missing param"); return; } 50 | UArray_appendCString_(self, s); 51 | } 52 | else if (*format == 'i' || *format == 'd') 53 | { 54 | int i = va_arg(ap, int); 55 | char s[100]; 56 | 57 | snprintf(s, 100, "%i", i); 58 | UArray_appendCString_(self, s); 59 | } 60 | else if (*format == 'f') 61 | { 62 | double d = va_arg(ap, double); 63 | char s[100]; 64 | 65 | snprintf(s, 100, "%f", d); 66 | UArray_appendCString_(self, s); 67 | } 68 | else if (*format == 'p') 69 | { 70 | void *p = va_arg(ap, void *); 71 | char s[100]; 72 | 73 | snprintf(s, 100, "%p", p); 74 | UArray_appendCString_(self, s); 75 | } 76 | // new format command for a given number adding spaces 77 | else if (*format == '#') 78 | { 79 | int n, i = va_arg(ap, int); 80 | char *s = " "; 81 | 82 | for (n = 0; n < i; n ++) 83 | { 84 | UArray_appendCString_(self, s); 85 | } 86 | } 87 | } 88 | else 89 | { 90 | char s[2]; 91 | 92 | snprintf(s, 2, "%c", *format); 93 | UArray_appendCString_(self, s); 94 | } 95 | 96 | format ++; 97 | } 98 | } 99 | 100 | UArray *UArray_asNewHexStringUArray(UArray *self) 101 | { 102 | size_t i, newSize = self->size * 2; 103 | UArray *ba = UArray_new(); 104 | UArray_setSize_(ba, newSize); 105 | 106 | for(i = 0; i < self->size; i ++) 107 | { 108 | int v = UArray_longAt_(self, i); 109 | char *s = (char *)(ba->data + i * 2); 110 | 111 | if (v < 16) 112 | { 113 | snprintf(s, newSize, "0%x", (int)v); 114 | } 115 | else 116 | { 117 | snprintf(s, newSize, "%x", (int)v); 118 | } 119 | } 120 | 121 | return ba; 122 | } 123 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_format.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | BASEKIT_API UArray *UArray_newWithFormat_(const char *format, ...); 7 | BASEKIT_API UArray *UArray_newWithVargs_(const char *format, va_list ap); 8 | BASEKIT_API UArray *UArray_fromFormat_(UArray *self, const char *format, ...); 9 | BASEKIT_API void UArray_fromVargs_(UArray *self, const char *format, va_list ap); 10 | 11 | BASEKIT_API UArray *UArray_asNewHexStringUArray(UArray *self); 12 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_math.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | // set 7 | 8 | BASEKIT_API void UArray_clear(UArray *self); 9 | BASEKIT_API void UArray_setItemsToLong_(UArray *self, long x); 10 | BASEKIT_API void UArray_setItemsToDouble_(UArray *self, double x); 11 | BASEKIT_API void UArray_rangeFill(UArray *self); 12 | BASEKIT_API void UArray_negate(const UArray *self); 13 | 14 | // basic vector math 15 | 16 | BASEKIT_API void UArray_add_(UArray *self, const UArray *other); 17 | BASEKIT_API void UArray_subtract_(UArray *self, const UArray *other); 18 | BASEKIT_API void UArray_multiply_(UArray *self, const UArray *other); 19 | BASEKIT_API void UArray_divide_(UArray *self, const UArray *other); 20 | BASEKIT_API double UArray_dotProduct_(const UArray *self, const UArray *other); 21 | 22 | // basic scalar math 23 | 24 | BASEKIT_API void UArray_addScalarDouble_(UArray *self, double v); 25 | BASEKIT_API void UArray_subtractScalarDouble_(UArray *self, double v); 26 | BASEKIT_API void UArray_multiplyScalarDouble_(UArray *self, double v); 27 | BASEKIT_API void UArray_divideScalarDouble_(UArray *self, double v); 28 | 29 | // bitwise logic 30 | 31 | BASEKIT_API void UArray_bitwiseOr_(UArray *self, const UArray *other); 32 | BASEKIT_API void UArray_bitwiseAnd_(UArray *self, const UArray *other); 33 | BASEKIT_API void UArray_bitwiseXor_(UArray *self, const UArray *other); 34 | BASEKIT_API void UArray_bitwiseNot(UArray *self); 35 | 36 | // bitwise ops 37 | 38 | BASEKIT_API void UArray_setAllBitsTo_(UArray *self, uint8_t aBool); 39 | BASEKIT_API uint8_t UArray_byteAt_(UArray *self, size_t i); 40 | BASEKIT_API int UArray_bitAt_(UArray *self, size_t i); 41 | BASEKIT_API void UArray_setBit_at_(UArray *self, int b, size_t i); 42 | BASEKIT_API UArray * UArray_asBits(const UArray *self); 43 | BASEKIT_API size_t UArray_bitCount(UArray *self); 44 | 45 | // boolean logic 46 | 47 | BASEKIT_API void UArray_logicalOr_(UArray *self, const UArray *other); 48 | BASEKIT_API void UArray_logicalAnd_(UArray *self, const UArray *other); 49 | 50 | // trigonometry 51 | 52 | BASEKIT_API void UArray_sin(UArray *self); 53 | BASEKIT_API void UArray_cos(UArray *self); 54 | BASEKIT_API void UArray_tan(UArray *self); 55 | 56 | BASEKIT_API void UArray_asin(UArray *self); 57 | BASEKIT_API void UArray_acos(UArray *self); 58 | BASEKIT_API void UArray_atan(UArray *self); 59 | 60 | //void UArray_atan2(UArray *self, const UArray *other); 61 | 62 | BASEKIT_API void UArray_sinh(UArray *self); 63 | BASEKIT_API void UArray_cosh(UArray *self); 64 | BASEKIT_API void UArray_tanh(UArray *self); 65 | 66 | BASEKIT_API void UArray_exp(UArray *self); 67 | BASEKIT_API void UArray_log(UArray *self); 68 | BASEKIT_API void UArray_log10(UArray *self); 69 | 70 | //void UArray_pow(UArray *self, const UArray *other); 71 | 72 | BASEKIT_API void UArray_sqrt(UArray *self); 73 | BASEKIT_API void UArray_ceil(UArray *self); 74 | BASEKIT_API void UArray_floor(UArray *self); 75 | BASEKIT_API void UArray_abs(UArray *self); 76 | BASEKIT_API void UArray_round(UArray *self); 77 | 78 | //void UArray_ldexp(UArray *self, const UArray *other); 79 | //void UArray_fmod(UArray *self, const UArray *other); 80 | 81 | BASEKIT_API void UArray_square(UArray *self); 82 | BASEKIT_API void UArray_normalize(UArray *self); 83 | 84 | BASEKIT_API void UArray_crossProduct_(UArray *self, const UArray *other); 85 | BASEKIT_API double UArray_distanceTo_(const UArray *self, const UArray *other); 86 | 87 | // extras 88 | 89 | BASEKIT_API double UArray_sumAsDouble(const UArray *self); 90 | BASEKIT_API double UArray_productAsDouble(const UArray *self); 91 | BASEKIT_API double UArray_arithmeticMeanAsDouble(const UArray *self); 92 | BASEKIT_API double UArray_arithmeticMeanSquareAsDouble(const UArray *self); 93 | BASEKIT_API double UArray_maxAsDouble(const UArray *self); 94 | BASEKIT_API double UArray_minAsDouble(const UArray *self); 95 | BASEKIT_API void UArray_Max(UArray *self, const UArray *other); 96 | BASEKIT_API void UArray_Min(UArray *self, const UArray *other); 97 | 98 | // hash 99 | 100 | BASEKIT_API void UArray_changed(UArray *self); 101 | BASEKIT_API uintptr_t UArray_calcHash(UArray *self); 102 | BASEKIT_API uintptr_t UArray_evenHash(UArray *self); 103 | BASEKIT_API uintptr_t UArray_oddHash(UArray *self); 104 | #define UArray_hash UArray_evenHash 105 | BASEKIT_API int UArray_equalsWithHashCheck_(UArray *self, UArray *other); 106 | 107 | // indexes 108 | 109 | BASEKIT_API void UArray_duplicateIndexes(UArray *self); 110 | BASEKIT_API void UArray_removeOddIndexes(UArray *self); 111 | BASEKIT_API void UArray_removeEvenIndexes(UArray *self); 112 | 113 | BASEKIT_API void UArray_reverseItemByteOrders(UArray *self); 114 | 115 | BASEKIT_API void UArray_addEqualsOffsetXScaleYScale(UArray *self, UArray *other, float offset, float xscale, float yscale); 116 | 117 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_path.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void UArray_appendPath_(UArray *self, const UArray *path) 13 | { 14 | const UArray sep = UArray_stackAllocedWithCString_(OS_PATH_SEPARATOR); 15 | 16 | int selfEndsWithSep = IS_PATH_SEPERATOR(UArray_lastLong(self)); 17 | int pathStartsWithSep = IS_PATH_SEPERATOR(UArray_firstLong(path)); 18 | 19 | if (!selfEndsWithSep && !pathStartsWithSep) 20 | { 21 | if(self->size != 0) UArray_append_(self, &sep); 22 | UArray_append_(self, path); 23 | } 24 | else if (selfEndsWithSep && pathStartsWithSep) 25 | { 26 | const UArray pathPart = UArray_stackRange(path, 1, path->size - 1); 27 | UArray_append_(self, &pathPart); 28 | } 29 | else 30 | { 31 | UArray_append_(self, path); 32 | } 33 | } 34 | 35 | void UArray_removeLastPathComponent(UArray *self) 36 | { 37 | long pos = UArray_findLastPathComponent(self); 38 | if (pos) pos --; 39 | UArray_setSize_(self, pos); 40 | } 41 | 42 | void UArray_clipBeforeLastPathComponent(UArray *self) 43 | { 44 | long pos = UArray_findLastPathComponent(self); 45 | 46 | if (pos != -1) 47 | { 48 | UArray_removeRange(self, 0, pos); 49 | } 50 | } 51 | 52 | long UArray_findLastPathComponent(const UArray *self) 53 | { 54 | if (self->size) 55 | { 56 | UArray seps = UArray_stackAllocedWithCString_(IO_PATH_SEPARATORS); 57 | UArray s = UArray_stackRange(self, 0, self->size); 58 | long pos = 0; 59 | 60 | while (s.size && (pos = UArray_rFindAnyValue_(&s, &seps)) == s.size - 1) 61 | { 62 | s.size = pos; 63 | } 64 | 65 | if (pos == -1) { pos = 0; } else { pos ++; } 66 | return pos; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | UArray *UArray_lastPathComponent(const UArray *self) 73 | { 74 | long pos = UArray_findLastPathComponent(self); 75 | return UArray_range(self, pos, self->size - pos); 76 | } 77 | 78 | long UArray_findPathExtension(UArray *self) 79 | { 80 | UArray dot = UArray_stackAllocedWithCString_(IO_PATH_SEPARATOR_DOT); 81 | return UArray_rFind_(self, &dot); 82 | } 83 | 84 | void UArray_removePathExtension(UArray *self) 85 | { 86 | long pos = UArray_findPathExtension(self); 87 | 88 | if (pos != -1) 89 | { 90 | UArray_setSize_(self, pos); 91 | } 92 | } 93 | 94 | UArray *UArray_pathExtension(UArray *self) 95 | { 96 | long pos = UArray_findPathExtension(self); 97 | 98 | if (pos == -1 || pos == self->size - 1) 99 | { 100 | return UArray_newWithCString_copy_("", 1); 101 | } 102 | 103 | return UArray_range(self, pos + 1, self->size - pos - 1); 104 | } 105 | 106 | UArray *UArray_fileName(UArray *self) 107 | { 108 | long extPos = UArray_findLastPathComponent(self); 109 | long dotPos = UArray_findPathExtension(self); 110 | 111 | //if (extPos == -1) { extPos = 0; } else { extPos ++; } 112 | if (dotPos == -1) dotPos = self->size; 113 | 114 | return UArray_range(self, extPos, dotPos - extPos); 115 | } 116 | 117 | // to/from os path - always returns a copy 118 | 119 | int UArray_OSPathSeparatorIsUnixSeparator(void) 120 | { 121 | return strcmp(OS_PATH_SEPARATOR, "/") == 0; 122 | } 123 | 124 | UArray *UArray_asOSPath(UArray *self) 125 | { 126 | UArray *a = UArray_clone(self); 127 | UArray_replaceCString_withCString_(a, IO_PATH_SEPARATOR, OS_PATH_SEPARATOR); 128 | return a; 129 | } 130 | 131 | UArray *UArray_asUnixPath(UArray *self) 132 | { 133 | UArray *a = UArray_clone(self); 134 | UArray_replaceCString_withCString_(a, OS_PATH_SEPARATOR, IO_PATH_SEPARATOR); 135 | return a; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_path.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | // internally, Io always uses a forward slash "/" for path separators, 7 | // but on Windows, back slashes are also tolerated as path separators. 8 | #if defined(DOS) || defined(ON_WINDOWS) 9 | #define OS_PATH_SEPARATOR "\\" 10 | #define IO_PATH_SEPARATORS "\\/" 11 | #else 12 | #define OS_PATH_SEPARATOR "/" 13 | #define IO_PATH_SEPARATORS "/" 14 | #endif 15 | 16 | #define IO_PATH_SEPARATOR "/" 17 | #define IO_PATH_SEPARATOR_DOT "." 18 | 19 | 20 | #ifdef ON_WINDOWS 21 | #define IS_PATH_SEPERATOR(ch) ((ch == '/') || (ch == '\\')) 22 | #else 23 | #define IS_PATH_SEPERATOR(ch) (ch == '/') 24 | #endif 25 | 26 | 27 | BASEKIT_API void UArray_appendPath_(UArray *self, const UArray *path); 28 | 29 | // last component 30 | 31 | BASEKIT_API void UArray_removeLastPathComponent(UArray *self); 32 | BASEKIT_API void UArray_clipBeforeLastPathComponent(UArray *self); 33 | BASEKIT_API long UArray_findLastPathComponent(const UArray *self); 34 | BASEKIT_API UArray *UArray_lastPathComponent(const UArray *self); 35 | 36 | // extension 37 | 38 | BASEKIT_API long UArray_findPathExtension(UArray *self); 39 | BASEKIT_API void UArray_removePathExtension(UArray *self); 40 | BASEKIT_API UArray *UArray_pathExtension(UArray *self); 41 | 42 | // fileName 43 | 44 | BASEKIT_API UArray *UArray_fileName(UArray *self); 45 | 46 | // to/from os path - always returns a copy 47 | 48 | BASEKIT_API int UArray_OSPathSeparatorIsUnixSeparator(void); 49 | BASEKIT_API UArray *UArray_asOSPath(UArray *self); 50 | BASEKIT_API UArray *UArray_asUnixPath(UArray *self); 51 | 52 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_stream.c: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | #include "UArray.h" 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // read ------------------------------------------------------ 13 | 14 | size_t UArray_fread_(UArray *self, FILE *fp) 15 | { 16 | size_t itemsRead = fread(self->data, self->itemSize, self->size, fp); 17 | UArray_setSize_(self, itemsRead); 18 | return itemsRead; 19 | } 20 | 21 | long UArray_readFromCStream_(UArray *self, FILE *fp) 22 | { 23 | long totalItemsRead = 0; 24 | long itemsPerBuffer = 4096 / self->itemSize; 25 | UArray *buffer = UArray_new(); 26 | UArray_setItemType_(buffer, self->itemType); 27 | UArray_setSize_(buffer, itemsPerBuffer); 28 | 29 | if (!fp) { perror("UArray_readFromCStream_"); return -1; } 30 | 31 | while(!feof(fp) && !ferror(fp)) 32 | { 33 | size_t itemsRead; 34 | UArray_setSize_(buffer, itemsPerBuffer); 35 | itemsRead = UArray_fread_(buffer, fp); 36 | 37 | totalItemsRead += itemsRead; 38 | UArray_append_(self, buffer); 39 | if (itemsRead != itemsPerBuffer) break; 40 | } 41 | 42 | if (ferror(fp)) { perror("UArray_readFromCStream_"); return -1; } 43 | 44 | UArray_free(buffer); 45 | return totalItemsRead; 46 | } 47 | 48 | long UArray_readNumberOfItems_fromCStream_(UArray *self, size_t size, FILE *stream) 49 | { 50 | size_t itemsRead; 51 | UArray *buffer = UArray_new(); 52 | UArray_setItemType_(buffer, self->itemType); 53 | UArray_setSize_(buffer, size); 54 | 55 | itemsRead = UArray_fread_(buffer, stream); 56 | UArray_append_(self, buffer); 57 | 58 | UArray_free(buffer); 59 | return itemsRead; 60 | } 61 | 62 | long UArray_readFromFilePath_(UArray *self, const UArray *path) 63 | { 64 | FILE *stream; 65 | long itemsRead; 66 | UArray *sysPath = (UArray_itemSize(path) == 1) ? (UArray *)path : UArray_asUTF8(path); 67 | const char *p = UArray_asCString(sysPath); 68 | 69 | //printf("UArray_readFromFilePath_(\"%s\")\n", p); 70 | 71 | stream = fopen(p, "rb"); 72 | if (!stream) return -1; 73 | itemsRead = UArray_readFromCStream_(self, stream); 74 | fclose(stream); 75 | 76 | if(sysPath != path) UArray_free(sysPath); 77 | return itemsRead; 78 | } 79 | 80 | 81 | #define CHUNK_SIZE 4096 82 | 83 | int UArray_readLineFromCStream_(UArray *self, FILE *stream) 84 | { 85 | int readSomething = 0; 86 | 87 | if(self->itemSize == 1) 88 | { 89 | char *s = (char *)io_calloc(1, CHUNK_SIZE); 90 | 91 | while (fgets(s, CHUNK_SIZE, stream) != NULL) 92 | { 93 | char *eol1 = strchr(s, '\n'); 94 | char *eol2 = strchr(s, '\r'); 95 | 96 | readSomething = 1; 97 | 98 | if (eol1) { *eol1 = 0; } // remove the \n return character 99 | if (eol2) { *eol2 = 0; } // remove the \r return character 100 | 101 | if (*s) 102 | { 103 | UArray_appendCString_(self, s); 104 | } 105 | 106 | if (eol1 || eol2) 107 | { 108 | break; 109 | } 110 | } 111 | 112 | io_free(s); 113 | } 114 | 115 | return readSomething; 116 | } 117 | 118 | // write ------------------------------------------------------ 119 | 120 | size_t UArray_fwrite_(const UArray *self, size_t size, FILE *fp) 121 | { 122 | return fwrite(self->data, 1, self->itemSize * size, fp); 123 | } 124 | 125 | long UArray_writeToCStream_(const UArray *self, FILE *stream) 126 | { 127 | size_t totalItemsRead = UArray_fwrite_(self, self->size, stream); 128 | if (ferror(stream)) { perror("UArray_readFromCStream_"); return -1; } 129 | return totalItemsRead; 130 | } 131 | 132 | long UArray_writeToFilePath_(const UArray *self, const UArray *path) 133 | { 134 | UArray *sysPath = (UArray_itemSize(path) == 1) ? (UArray *)path : UArray_asUTF8(path); 135 | FILE *fp = fopen(UArray_asCString(sysPath), "w"); 136 | long itemsWritten = -1; 137 | 138 | if (fp) 139 | { 140 | itemsWritten = UArray_writeToCStream_(self, fp); 141 | fclose(fp); 142 | } 143 | 144 | return itemsWritten; 145 | } 146 | 147 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | // these return item read/written count or -1 on error 7 | 8 | // read 9 | 10 | BASEKIT_API size_t UArray_fread_(UArray *self, FILE *fp); 11 | BASEKIT_API long UArray_readFromCStream_(UArray *self, FILE *stream); 12 | BASEKIT_API long UArray_readFromFilePath_(UArray *self, const UArray *path); 13 | BASEKIT_API long UArray_readNumberOfItems_fromCStream_(UArray *self, size_t size, FILE *stream); 14 | BASEKIT_API int UArray_readLineFromCStream_(UArray *self, FILE *stream); 15 | 16 | // write 17 | 18 | BASEKIT_API size_t UArray_fwrite_(const UArray *self, size_t size, FILE *stream); 19 | BASEKIT_API long UArray_writeToCStream_(const UArray *self, FILE *stream); 20 | BASEKIT_API long UArray_writeToFilePath_(const UArray *self, const UArray *path); 21 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | /* 7 | copyright: Steve Dekorte, 2006. All rights reserved. 8 | license: See _BSDLicense.txt. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | BASEKIT_API void UArray_append_(UArray *self, const UArray *other); 17 | BASEKIT_API void UArray_appendCString_(UArray *self, const char *s); 18 | BASEKIT_API void UArray_prepend_(UArray *self, const UArray *other); 19 | 20 | BASEKIT_API int UArray_equalsAnyCase_(const UArray *self, const UArray *other); 21 | BASEKIT_API void UArray_replace_with_(UArray *self, const UArray *a1, const UArray *a2); 22 | BASEKIT_API void UArray_replaceAnyCase_with_(UArray *self, const UArray *a1, const UArray *a2); 23 | BASEKIT_API void UArray_replaceCString_withCString_(UArray *self, const char *s1, const char *s2); 24 | BASEKIT_API void UArray_remove_(UArray *self, const UArray *a1); 25 | BASEKIT_API void UArray_removeAnyCase_(UArray *self, const UArray *a1); 26 | 27 | // clipping 28 | 29 | BASEKIT_API int UArray_clipBefore_(UArray *self, const UArray *other); 30 | BASEKIT_API int UArray_clipBeforeEndOf_(UArray *self, const UArray *other); 31 | BASEKIT_API int UArray_clipAfter_(UArray *self, const UArray *other); 32 | BASEKIT_API int UArray_clipAfterStartOf_(UArray *self, const UArray *other); 33 | 34 | // strip 35 | 36 | BASEKIT_API void UArray_lstrip_(UArray *self, const UArray *other); 37 | BASEKIT_API void UArray_rstrip_(UArray *self, const UArray *other); 38 | BASEKIT_API void UArray_strip_(UArray *self, const UArray *other); 39 | 40 | // swap 41 | 42 | BASEKIT_API void UArray_swapIndex_withIndex_(UArray *self, size_t i, size_t j); 43 | 44 | // reverse 45 | 46 | BASEKIT_API void UArray_reverse(UArray *self); 47 | 48 | //BASEKIT_API size_t UArray_matchingPrefixSizeWith_(const UArray *self, const UArray *other); 49 | 50 | // split 51 | 52 | BASEKIT_API PtrUArray *UArray_split_(const UArray *self, const PtrUArray *delims); 53 | BASEKIT_API size_t UArray_splitCount_(const UArray *self, const PtrUArray *delims); 54 | 55 | // find 56 | 57 | BASEKIT_API int UArray_beginsWith_(UArray *self, const UArray *other); 58 | BASEKIT_API int UArray_endsWith_(UArray *self, const UArray *other); 59 | 60 | // escape and quote 61 | 62 | BASEKIT_API void UArray_swapWith_(UArray *self, UArray *other); 63 | 64 | BASEKIT_API void UArray_escape(UArray *self); 65 | BASEKIT_API void UArray_unescape(UArray *self); 66 | 67 | BASEKIT_API void UArray_quote(UArray *self); 68 | BASEKIT_API void UArray_unquote(UArray *self); 69 | 70 | BASEKIT_API void UArray_translate(UArray *self, UArray *fromChars, UArray *toChars); 71 | BASEKIT_API size_t UArray_count_(const UArray *self, const UArray *other); 72 | 73 | // encoding 74 | 75 | BASEKIT_API UArray* UArray_asBase64(const UArray *self); 76 | BASEKIT_API UArray* UArray_fromBase64(const UArray *self); 77 | -------------------------------------------------------------------------------- /source/basekit/source/UArray_utf.h: -------------------------------------------------------------------------------- 1 | /* 2 | copyright: Steve Dekorte, 2006. All rights reserved. 3 | license: See _BSDLicense.txt. 4 | */ 5 | 6 | BASEKIT_API int UArray_convertToFixedSizeType(UArray *self); 7 | 8 | BASEKIT_API size_t UArray_numberOfCharacters(const UArray *self); // returns 0 on error 9 | 10 | BASEKIT_API int UArray_maxCharSize(const UArray *self); 11 | BASEKIT_API int UArray_isMultibyte(const UArray *self); 12 | BASEKIT_API int UArray_isLegalUTF8(const UArray *self); 13 | 14 | BASEKIT_API UArray *UArray_asUTF8(const UArray *self); 15 | BASEKIT_API UArray *UArray_asUCS2(const UArray *self); 16 | BASEKIT_API UArray *UArray_asUCS4(const UArray *self); 17 | 18 | BASEKIT_API void UArray_convertToUTF8(UArray *self); 19 | BASEKIT_API void UArray_convertToUCS2(UArray *self); 20 | BASEKIT_API void UArray_convertToUCS4(UArray *self); 21 | -------------------------------------------------------------------------------- /source/basekit/source/_new/Directory.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | /* ----------------------------------------------------- */ 6 | 7 | #include 8 | 9 | #ifndef _WIN32 10 | #include 11 | #include 12 | 13 | /*#ifdef __CYGWIN__*/ 14 | #include 15 | /*#endif*/ 16 | #else 17 | #include 18 | #define S_IRGRP 0 19 | #define S_IXGRP 0 20 | #define S_IROTH 0 21 | #define S_IXOTH 0 22 | #define S_IRWXU 0 23 | 24 | #define DT_DIR 0x01 25 | 26 | struct dirent { 27 | char d_name[MAX_PATH]; 28 | unsigned char d_type; 29 | }; 30 | 31 | typedef struct { 32 | WIN32_FIND_DATA wfd; 33 | HANDLE hFind; 34 | struct dirent de; 35 | unsigned char valid; 36 | } DIR; 37 | 38 | static DIR *opendir(char *pSpec) 39 | { 40 | DIR *pDir = malloc(sizeof *pDir); 41 | char *longer_string = malloc((strlen(pSpec) + 3) * sizeof *longer_string); 42 | 43 | strcpy(longer_string, pSpec); 44 | strcat(longer_string, "/*"); 45 | pDir->hFind = FindFirstFile(longer_string, &pDir->wfd); 46 | free(longer_string); 47 | pDir->valid = pDir->hFind != INVALID_HANDLE_VALUE; 48 | return pDir; 49 | } 50 | 51 | static void closedir(DIR * pDir) 52 | { 53 | if (pDir->hFind != INVALID_HANDLE_VALUE) 54 | FindClose(pDir->hFind); 55 | free(pDir); 56 | } 57 | 58 | static struct dirent *readdir(DIR *pDir) 59 | { 60 | if (pDir->valid) 61 | { 62 | strcpy(pDir->de.d_name, pDir->wfd.cFileName); 63 | pDir->de.d_type = (pDir->wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ? DT_DIR : 0; 64 | pDir->valid = FindNextFile(pDir->hFind, &pDir->wfd); 65 | return &pDir->de; 66 | } 67 | return NULL; 68 | } 69 | 70 | typedef int mode_t; 71 | 72 | int mkdir(const char *path, mode_t mode) 73 | { 74 | /* returns zero on sucess */ 75 | LPCTSTR lpPathName = path; 76 | LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL; 77 | return (CreateDirectory(lpPathName, lpSecurityAttributes) != 0); 78 | } 79 | 80 | #endif 81 | 82 | #if defined(__CYGWIN__) || defined(sun) || defined(__sun) 83 | int isDirectory(struct dirent *dp, char *path); 84 | { 85 | struct stat st; 86 | /*fstat( dp->d_fd, &st );*/ 87 | stat(pathString, &st); 88 | return ( (st.st_mode & S_IFMT) == S_IFDIR ); 89 | } 90 | #else 91 | int isDirectory(struct dirent *dp, char *path) 92 | { 93 | return (dp->d_type == DT_DIR); 94 | } 95 | #endif 96 | 97 | /* ----------------------------------------------------- */ 98 | 99 | typedef struct 100 | { 101 | char *path; 102 | DIR *dir; 103 | char *next; 104 | } DirEnum; 105 | 106 | DirEnum *DirEnum_new(void) 107 | { 108 | DirEnum *self = calloc(1, sizeof(DirEnum)); 109 | return self; 110 | } 111 | 112 | void DirEnum_free(DirEnum *self) 113 | { 114 | if (self->path) free(self->path); 115 | free(self); 116 | } 117 | 118 | void DirEnum_setPath_(DirEnum *self, char *s) 119 | { 120 | self->path = strcpy(realloc(self->path, strlen(s) + 1), s); 121 | self->dir = opendir(s); 122 | } 123 | 124 | char *DirEnum_setNext_(DirEnum *self, char *s) 125 | { 126 | self->next = strcpy(realloc(self->next, strlen(s) + 1), s); 127 | return self->next; 128 | } 129 | 130 | char *DirEnum_next(DirEnum *self) 131 | { 132 | struct direct *dp = readdir(dirp); 133 | if (dp) 134 | { 135 | char *name = dp.d_name; 136 | } 137 | } 138 | 139 | -------------------------------------------------------------------------------- /source/basekit/source/cdecode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cdecoder.c - c source to a base64 decoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #include "cdecode.h" 9 | 10 | int base64_decode_value(char value_in) 11 | { 12 | static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; 13 | static const char decoding_size = sizeof(decoding); 14 | value_in -= 43; 15 | if (value_in < 0 || value_in > decoding_size) return -1; 16 | return decoding[(int)value_in]; 17 | } 18 | 19 | void base64_init_decodestate(base64_decodestate* state_in) 20 | { 21 | state_in->step = step_a; 22 | state_in->plainchar = 0; 23 | } 24 | 25 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) 26 | { 27 | const char* codechar = code_in; 28 | char* plainchar = plaintext_out; 29 | char fragment; 30 | 31 | *plainchar = state_in->plainchar; 32 | 33 | switch (state_in->step) 34 | { 35 | while (1) 36 | { 37 | case step_a: 38 | do { 39 | if (codechar == code_in+length_in) 40 | { 41 | state_in->step = step_a; 42 | state_in->plainchar = *plainchar; 43 | return (int)(plainchar - plaintext_out); 44 | } 45 | fragment = (char)base64_decode_value(*codechar++); 46 | } while (fragment < 0); 47 | *plainchar = (fragment & 0x03f) << 2; 48 | case step_b: 49 | do { 50 | if (codechar == code_in+length_in) 51 | { 52 | state_in->step = step_b; 53 | state_in->plainchar = *plainchar; 54 | return (int)(plainchar - plaintext_out); 55 | } 56 | fragment = (char)base64_decode_value(*codechar++); 57 | } while (fragment < 0); 58 | *plainchar++ |= (fragment & 0x030) >> 4; 59 | *plainchar = (fragment & 0x00f) << 4; 60 | case step_c: 61 | do { 62 | if (codechar == code_in+length_in) 63 | { 64 | state_in->step = step_c; 65 | state_in->plainchar = *plainchar; 66 | return (int)(plainchar - plaintext_out); 67 | } 68 | fragment = (char)base64_decode_value(*codechar++); 69 | } while (fragment < 0); 70 | *plainchar++ |= (fragment & 0x03c) >> 2; 71 | *plainchar = (fragment & 0x003) << 6; 72 | case step_d: 73 | do { 74 | if (codechar == code_in+length_in) 75 | { 76 | state_in->step = step_d; 77 | state_in->plainchar = *plainchar; 78 | return (int)(plainchar - plaintext_out); 79 | } 80 | fragment = (char)base64_decode_value(*codechar++); 81 | } while (fragment < 0); 82 | *plainchar++ |= (fragment & 0x03f); 83 | } 84 | } 85 | /* control should not reach here */ 86 | return (int)(plainchar - plaintext_out); 87 | } 88 | -------------------------------------------------------------------------------- /source/basekit/source/cdecode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cdecode.h - c header for a base64 decoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CDECODE_H 9 | #define BASE64_CDECODE_H 10 | 11 | typedef enum 12 | { 13 | step_a, step_b, step_c, step_d 14 | } base64_decodestep; 15 | 16 | typedef struct 17 | { 18 | base64_decodestep step; 19 | char plainchar; 20 | } base64_decodestate; 21 | 22 | void base64_init_decodestate(base64_decodestate* state_in); 23 | 24 | int base64_decode_value(char value_in); 25 | 26 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); 27 | 28 | #endif /* BASE64_CDECODE_H */ 29 | -------------------------------------------------------------------------------- /source/basekit/source/cencode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cencoder.c - c source to a base64 encoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #include "cencode.h" 9 | #include 10 | 11 | const int CHARS_PER_LINE = 72; 12 | 13 | void base64_init_encodestate(base64_encodestate* state_in) 14 | { 15 | state_in->step = step_A; 16 | state_in->result = 0; 17 | state_in->stepcount = 0; 18 | } 19 | 20 | char base64_encode_value(char value_in) 21 | { 22 | static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 23 | if (value_in > 63) return '='; 24 | return encoding[(int)value_in]; 25 | } 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) 28 | { 29 | const char* plainchar = plaintext_in; 30 | const char* const plaintextend = plaintext_in + length_in; 31 | char* codechar = code_out; 32 | char result; 33 | char fragment; 34 | 35 | result = state_in->result; 36 | 37 | switch (state_in->step) 38 | { 39 | while (1) 40 | { 41 | case step_A: 42 | if (plainchar == plaintextend) 43 | { 44 | state_in->result = result; 45 | state_in->step = step_A; 46 | return codechar - code_out; 47 | } 48 | fragment = *plainchar++; 49 | result = (fragment & 0x0fc) >> 2; 50 | *codechar++ = base64_encode_value(result); 51 | result = (fragment & 0x003) << 4; 52 | case step_B: 53 | if (plainchar == plaintextend) 54 | { 55 | state_in->result = result; 56 | state_in->step = step_B; 57 | return codechar - code_out; 58 | } 59 | fragment = *plainchar++; 60 | result |= (fragment & 0x0f0) >> 4; 61 | *codechar++ = base64_encode_value(result); 62 | result = (fragment & 0x00f) << 2; 63 | case step_C: 64 | if (plainchar == plaintextend) 65 | { 66 | state_in->result = result; 67 | state_in->step = step_C; 68 | return codechar - code_out; 69 | } 70 | fragment = *plainchar++; 71 | result |= (fragment & 0x0c0) >> 6; 72 | *codechar++ = base64_encode_value(result); 73 | result = (fragment & 0x03f) >> 0; 74 | *codechar++ = base64_encode_value(result); 75 | 76 | ++(state_in->stepcount); 77 | if (state_in->stepcount == CHARS_PER_LINE/4) 78 | { 79 | *codechar++ = '\n'; 80 | state_in->stepcount = 0; 81 | } 82 | } 83 | } 84 | /* control should not reach here */ 85 | return codechar - code_out; 86 | } 87 | 88 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in) 89 | { 90 | char* codechar = code_out; 91 | 92 | switch (state_in->step) 93 | { 94 | case step_B: 95 | *codechar++ = base64_encode_value(state_in->result); 96 | *codechar++ = '='; 97 | *codechar++ = '='; 98 | break; 99 | case step_C: 100 | *codechar++ = base64_encode_value(state_in->result); 101 | *codechar++ = '='; 102 | break; 103 | case step_A: 104 | break; 105 | } 106 | *codechar++ = '\n'; 107 | 108 | return codechar - code_out; 109 | } 110 | -------------------------------------------------------------------------------- /source/basekit/source/cencode.h: -------------------------------------------------------------------------------- 1 | /* 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CENCODE_H 9 | #define BASE64_CENCODE_H 10 | 11 | typedef enum 12 | { 13 | step_A, step_B, step_C 14 | } base64_encodestep; 15 | 16 | typedef struct 17 | { 18 | base64_encodestep step; 19 | char result; 20 | int stepcount; 21 | } base64_encodestate; 22 | 23 | void base64_init_encodestate(base64_encodestate* state_in); 24 | 25 | char base64_encode_value(char value_in); 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 28 | 29 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 30 | 31 | #endif /* BASE64_CENCODE_H */ 32 | 33 | -------------------------------------------------------------------------------- /source/basekit/source/simd_cph/LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | -------------------------------------------------------------------------------- /source/basekit/source/simd_cph/docs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | -------------------------------------------------------------------------------- /source/basekit/source/simd_cph/include/simd_cp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | 30 | 31 | /***************************************************** 32 | 33 | Cross-platform SIMD intrinsics header file 34 | 35 | This is the main file and the only one an application should 36 | include. It will find the correct (hopefully) SIMD_CPH 37 | dialect file to include. 38 | 39 | 40 | */ 41 | 42 | #ifndef __SIMD_CPHD_h 43 | 44 | 45 | /* Defines */ 46 | /* Defines */ 47 | /* Defines */ 48 | #define __SIMD_CPHD_h 49 | 50 | 51 | /* Figure out what compiler and CPU we have */ 52 | 53 | #if defined (__SIMD_NO_SIMD__) || defined (__SIMD_EMU__) 54 | #else /* broken pre-processor */ 55 | 56 | #ifdef __GNUC__ /* gcc compiler */ 57 | 58 | /* x86 compiler */ 59 | #ifdef __i386__ 60 | #define __GNUC__X86__ 61 | #define __FOUND 62 | #endif 63 | 64 | /* PowerPC Compiler */ 65 | #ifdef __ALTIVEC__ 66 | #define __GNUC__RS6__ 67 | #define __FOUND 68 | #define __SIMD_NO_SIMD /* No PPC intrinsics file right now */ 69 | #endif 70 | 71 | #ifdef __XSCALE__ 72 | #define __GNUC__ARM_IWMMX__ 73 | #define __FOUND 74 | #endif 75 | 76 | #endif /* __GNUC__ */ 77 | 78 | 79 | 80 | #ifdef _MSC_VER /* Microsoft VC Compiler */ 81 | 82 | #ifdef _M_IX86 /* MSVC for X86 CPU (same as GNUC?)*/ 83 | #define __MSVC__X86__ 84 | #define __FOUND 85 | #endif 86 | 87 | #ifdef _M_ALPHA /* for Compaq Alpha CPU */ 88 | #define __MSVC__AXP__ 89 | #define __FOUND 90 | #define __SIMD_NO_SIMD__ 91 | #endif 92 | 93 | #endif /* _WIN32 */ 94 | 95 | 96 | 97 | #ifndef __FOUND 98 | #define __SIMD_EMU__ 99 | //#warning simd_cp.h does not support or could not figure out your compiler and/or CPU. 100 | #endif 101 | 102 | #endif /* SIMD_NO_SIMD and SIMD_EMU */ 103 | 104 | 105 | /* Include the correct SIMD file */ 106 | 107 | #if defined(__SIMD_NO_SIMD__) || defined(__SIMD_EMU__) 108 | #warning Including Emulated SIMD support... 109 | #define __UNK__EMU__ 110 | #include 111 | #endif 112 | 113 | #if defined( __GNUC__X86__ ) || defined(__MSVC__X86__) 114 | /* gcc x86 compiler or msvc x86 */ 115 | #include 116 | #endif /* __GNUC__X86__ */ 117 | 118 | #ifdef __GNUC__ARM_IWMMX /* gcc ARM compiler with XSCALE SIMD */ 119 | #include 120 | #endif 121 | 122 | 123 | /* Generic Helper commands */ 124 | /* Generic Helper commands */ 125 | /* Generic Helper commands */ 126 | 127 | /* print a simd_m128 variable: l=label to print, a=simd_m128 variable */ 128 | #define simd_print4Floats(l,a) printf("%s: %f %f %f %f\n",l,a.f[0],a.f[1],a.f[2],a.f[3]) 129 | #define simd_print4Ints(l,a) printf("%s: %d %d %d %d\n",l,a.i[0],a.i[1],a.i[2],a.i[3]) 130 | #define simd_print4UInts(l,a) printf("%s: %d %d %d %d\n",l,(unsigned int)a.i[0],(unsigned int)a.i[1],(unsigned int)a.i[2],(unsigned int)a.i[3]) 131 | #define simd_print4Hex(l,a) printf("%s: 0x%08x 0x%08x 0x%08x 0x%08x\n",l,a.i[0],a.i[1],a.i[2],a.i[3]) 132 | 133 | 134 | #endif /* CP_SIMD_h */ 135 | -------------------------------------------------------------------------------- /source/basekit/source/simd_cph/simd_cph.readme: -------------------------------------------------------------------------------- 1 | /***************************************************** 2 | 3 | Cross-platform SIMD intrinsics header file 4 | 5 | VERSION: 2004.10.26 (alpha) 6 | 7 | Created by Patrick Roberts 8 | 9 | This is an on-going project. Please add functions and 10 | typedefs as needed, but try to follow the guideline 11 | below: 12 | 13 | The goal of this file is to stay cross-platform. 14 | Only intrinsics or #defines that mimic another system's 15 | SIMD instruction should be included, with the only exception 16 | being instructions that, if non existant, are not 17 | needed (see bottom) 18 | 19 | Currently, the goal is to base support around 128-bit SIMD. 20 | (Only the Gekko and x86-MMX are 64-bit) 21 | 22 | Changelog: 23 | 24 | 2004.05.09 [Patrick Roberts] 25 | *) Created file with some i386, GCC dialect 26 | 2004.10.22 [Patrick Roberts] 27 | *) Created emulated SIMD 28 | 2004.10.25 [Patrick Roberts] 29 | *) Created arm-iwmmx GCC dialect 30 | *) Fixed sqrt bug in emu dialect 31 | *) Organized directories 32 | *) Makefile for test app 33 | 34 | 35 | To Do: 36 | 37 | *( Docs 38 | *( Add new intrinsics to test app 39 | *( MinGW x86 dialect (same as GCC on Linux?) 40 | *( Does 3DNOW buy us anything? 41 | *( Intel ICC x86 dialect 42 | *( MSVC .NET x86 dialect 43 | *( Support for ARM ARM6, VFP and NEON SIMD? What compilers use these? 44 | *( PowerPC AltiVec/Velocity/VMX components 45 | *( MIPS-MMI / PS2-VU components 46 | *( See if SSE2 buys us anything beyond what the compiler does already 47 | *( Compaq Alpha components 48 | 49 | */ 50 | 51 | /*************************************************** 52 | 53 | Platform Notes: 54 | 55 | 56 | General 57 | ------- 58 | 59 | NOTE: Code must be 16-byte aligned. Align to 16 when allocating memory. 60 | 61 | X86/XSCALE (Intel) vs. PowerPC/MIPS 62 | 63 | While the PowerPC and MIPS SIMD instructions take 2 source vectors 64 | and a destination vector, the Intel platforms only take a source and 65 | destination. Example: 66 | 67 | PPC/MIPS can do: 68 | 69 | C = A + B 70 | 71 | X86 can only do: 72 | 73 | A = A + B (or A+=B) 74 | 75 | Code written either way will work on the X86, and still be faster than 76 | 387 math, but preserving the registers takes significant overhead. 77 | (Disassemble the test program for an example. The prints preserve, the 78 | 'disassembly test' does not.) For the fastest code between systems, write 79 | your SIMD math as the X86 expects, manually preserving SIMD variables. 80 | At least GCC for PPC doesn't seem to have any issues figuring out how to 81 | deal with a source and destination memory address being the same. 82 | 83 | 84 | GCC x86 85 | ------- 86 | 87 | You must compile with -msse and -mmmx. I try to avoid mmx as mmx is slower on 88 | the P4 than on the P3 and XP, but sse doesn't have integer math. 89 | 90 | You may want to set -msse2 if you have a P4 CPU (-msse2 is set by default 91 | for x86-64 CPUS), as some of the simd functions not supported on x86 92 | can be sped up by gcc using sse2 commands rather than standard pipeline 93 | commands. 94 | 95 | 96 | GCC PowerPC 97 | ----------- 98 | 99 | You must compile with the switch -maltivec 100 | 101 | 102 | GCC ARM (Xscale only) 103 | ---------------- 104 | 105 | GCC ARM only seems to support Intel Wirekess MMX (XSCALE), not ARMv6, 106 | Neon, or VFP? (Are these all the same beast?) 107 | 108 | You must compile with +iwmmxt 109 | 110 | 111 | */ 112 | -------------------------------------------------------------------------------- /source/basekit/source/simd_cph/test/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CC = gcc 3 | 4 | # X86 5 | #COPTS = -I../include -g -O2 -mmmx -msse 6 | #PLATFORM = X86 7 | DIS = objdump -d -S 8 | 9 | # EMULATED 10 | COPTS = -I../include -D__SIMD_EMU__ -g -O2 11 | PLATFORM = emu 12 | 13 | default: test_simd.c emulated 14 | ${CC} ${COPTS} -o test_simd_${PLATFORM} test_simd.c 15 | 16 | emulated: test_simd.c 17 | ${CC} ${COPTS} -D__SIMD_EMU__ -o test_simd_emu test_simd.c 18 | 19 | xdiff: default emulated 20 | ${DIS} test_simd_${PLATFORM} > test_simd_${PLATFORM}.dis 21 | ${DIS} test_simd_emu > test_simd_emu.dis 22 | xdiff test_simd_emu.dis test_simd_${PLATFORM}.dis 23 | 24 | clean: 25 | rm test_simd_${PLATFORM} test_simd_emu *.dis 26 | -------------------------------------------------------------------------------- /source/basekit/source/simd_cph/test/test_simd.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004 Patrick Roberts 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be held 6 | liable for any damages arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any 9 | purpose, including commercial applications, and to alter it 10 | and redistribute it freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; 13 | you must not claim that you wrote the original software. 14 | If you use this software in a product, an acknowledgment in 15 | the product documentation would be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, 18 | and must not be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source distribution. 21 | 22 | 4. THIS LICENSE MAY NOT BE CHANGED, ASSIGNED, OR MIGRATED WITHOUT 23 | THE AUTHOR'S WRITTEN PERMISSION, WITH THE FOLLOWING EXCEPTIONS: 24 | 25 | a. This file may be included with GPL/LGPL licensed 26 | software, but you may not change the license this file 27 | is released under. 28 | */ 29 | 30 | 31 | /* uncomment the line below to force SIMD emulation C code */ 32 | /*#define __SIMD_EMU__ */ 33 | 34 | #include 35 | #include 36 | 37 | int main(void) { 38 | 39 | simd_m128 v0,v1,v2; 40 | 41 | simd_load4Floats(v1,2.0,2.0,2.0,2.0); 42 | simd_load4Floats(v2,10.0,20.0,30.0,40.0); 43 | 44 | printf("\nChecking 4f commands\n"); 45 | 46 | simd_print4Floats("v1 ",v1); 47 | simd_print4Floats("v2 ",v2); 48 | puts(""); 49 | 50 | /* v0 = v1 + v2 */ 51 | simd_4f_add(v1,v2,v0); 52 | simd_print4Floats("4f_add ",v0); 53 | 54 | /* v0 = v1 - v2 */ 55 | simd_4f_sub(v1,v2,v0); 56 | simd_print4Floats("4f_sub ",v0); 57 | 58 | /* v0 = v1 * v2 */ 59 | simd_4f_mult(v1,v2,v0); 60 | simd_print4Floats("4f_mult",v0); 61 | 62 | /* v0 = v1 / v2 */ 63 | simd_4f_div(v1,v2,v0); 64 | simd_print4Floats("4f_div",v0); 65 | 66 | /* 67 | * If you look at the disassembly of this section on an X86 processor, it will be 68 | * very tight, as X86 SSE/MMX only handles 2 regs- i.e. A+=B, instead of C=A+B. 69 | * For the best cross-platform performance, cater to the lowest demoninator and 70 | * write your code like this. 71 | */ 72 | 73 | printf("\ndisassembly test\n"); 74 | simd_4f_add(v1,v2,v1); 75 | simd_4f_mult(v1,v2,v1); 76 | simd_4f_sub(v1,v2,v1); 77 | simd_4f_div(v1,v2,v1); 78 | 79 | 80 | 81 | printf("\nChecking 4i commands\n"); 82 | 83 | simd_load4Ints(v1,20,30,40,50); 84 | simd_load4Ints(v2,2,3,4,5); 85 | 86 | simd_print4Ints("v1 ",v1); 87 | simd_print4Ints("v2 ",v2); 88 | puts(""); 89 | 90 | 91 | /* v0 = v1 + v2 */ 92 | simd_4i_add(v1,v2,v0); 93 | simd_print4Ints("4i_add ",v0); 94 | 95 | /* v0 = v1 - v2 */ 96 | simd_4i_sub(v1,v2,v0); 97 | simd_print4Ints("4i_sub ",v0); 98 | 99 | /* v0 = v1 * v2 */ 100 | simd_4i_mult(v1,v2,v0); 101 | simd_print4Ints("4i_mult",v0); 102 | 103 | /* v0 = v1 / v2 */ 104 | simd_4i_div(v1,v2,v0); 105 | simd_print4Ints("4i_div ",v0); 106 | 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /source/basekit/source/simd_cph/test/test_simd_emu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/vertexdb/8fbb2fa0a750bb100a8d6563fefa7721ee2b6b02/source/basekit/source/simd_cph/test/test_simd_emu -------------------------------------------------------------------------------- /source/basekit/source/ucs2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | /**@CFILE ucs2.c UCS2 (Unicode, ISO Basic Multilingual Plane) string handling. 26 | * 27 | * @author Pekka Pessi 28 | * 29 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 30 | * 31 | */ 32 | 33 | //#include "config.h" 34 | 35 | #include "utf8.h" 36 | #include "utf8internal.h" 37 | 38 | /* 39 | * Decode utf8 string into ucs2 string, 40 | * return number of ucs2 characters decoded 41 | */ 42 | size_t ucs2decode(ucs2 *dst, size_t dst_size, const utf8 *s) 43 | { 44 | ucs2 v, *d = dst; 45 | 46 | if (s) do { 47 | if (dst_size == 0) 48 | break; 49 | if (IS_UTF8_S1(s)) 50 | v = UCS4_S1(s), s += 1; 51 | else if (IS_UTF8_S2(s)) 52 | v = UCS4_S2(s), s += 2; 53 | else if (IS_UTF8_S3(s)) 54 | v = UCS4_S3(s), s += 3; 55 | else { 56 | s++; 57 | continue; /* skip illegal characters */ 58 | } 59 | *d++ = v; 60 | dst_size--; 61 | } while (*s); 62 | 63 | if (dst_size) 64 | *d = 0; 65 | 66 | return d - dst; 67 | } 68 | 69 | /* 70 | * Encode ucs2 string into utf8 string, 71 | * return number of utf8 bytes encoded including final zero 72 | * 73 | * 'quote' may contain an optional quoting table containing 74 | * non-zero for all ASCII characters to quote 75 | * 76 | */ 77 | size_t ucs2encode(utf8 *dst, const ucs2 *s, size_t n, const char quote[128]) 78 | { 79 | utf8 *d = dst; 80 | ucs2 c; 81 | 82 | if (s) while (n-- > 0) { 83 | c = *s++; 84 | 85 | if (IS_UCS4_1(c)) { 86 | if (quote && quote[c]) { 87 | UTF8_S2(d, c); 88 | d += 2; 89 | } 90 | else { 91 | if (!c) /* zero must be represented as UTF8_2 */ 92 | break; 93 | UTF8_S1(d, (utf8) c); 94 | d += 1; 95 | } 96 | } 97 | else if (IS_UCS4_2(c)) { 98 | UTF8_S2(d, c); 99 | d += 2; 100 | } 101 | else /* if (IS_UCS4_3(c)) */ { 102 | UTF8_S3(d, c); 103 | d += 3; 104 | } 105 | } 106 | 107 | *d++ = 0; 108 | return d - dst; 109 | } 110 | 111 | /* 112 | * Length of UCS2 (BMP, Unicode) string decoded from UTF8 113 | */ 114 | size_t ucs2declen(const utf8 *s) 115 | { 116 | size_t len = 0; 117 | size_t errors = 0; /* errors */ 118 | 119 | UTF8_ANALYZE(s, len, len, len, errors, errors); 120 | 121 | if (errors) 122 | return 0; 123 | 124 | return len; 125 | } 126 | 127 | /* 128 | * Length of UTF8 encoding of a UCS2 string, including final zero 129 | */ 130 | size_t ucs2enclen(const ucs2 *s, size_t n, const char quote[128]) 131 | { 132 | size_t len = 1; 133 | ucs2 c; 134 | 135 | while (n-- > 0) { 136 | c = *s++; 137 | if (c < 0x80u) 138 | if (quote && quote[c]) 139 | len += 2; 140 | else { 141 | if (!c) break; 142 | len += 1; 143 | } 144 | else if (c < 0x800u) 145 | len += 2; 146 | else /* if (c < 0x10000u) */ 147 | len += 3; 148 | } 149 | 150 | return len; 151 | } 152 | 153 | /* 154 | * Length of UCS2 string (number of non-zero UCS2 characters before zero) 155 | */ 156 | size_t ucs2len(ucs2 const *s) 157 | { 158 | size_t len = 0; 159 | 160 | if (s) while (*s++) 161 | len++; 162 | 163 | return len; 164 | } 165 | 166 | /* 167 | * Compare UCS2 (BMP, Unicode) string 168 | */ 169 | int ucs2cmp(ucs2 const *s1, ucs2 const *s2) 170 | { 171 | int retval = s1 - s2; 172 | 173 | if (s1 && s2) 174 | while ((retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 175 | ; 176 | 177 | return retval; 178 | } 179 | 180 | /* 181 | * Compare UCS2 (BMP, Unicode) string 182 | */ 183 | int ucs2ncmp(ucs2 const *s1, ucs2 const *s2, size_t n) 184 | { 185 | int retval = 0; 186 | 187 | if (s1 && s2) 188 | while (n-- > 0 && (retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 189 | ; 190 | 191 | return retval; 192 | } 193 | -------------------------------------------------------------------------------- /source/basekit/source/ucs4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | /**@CFILE ucs4.c UCS-4 routines 26 | * 27 | * @author Pekka Pessi 28 | * 29 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 30 | */ 31 | 32 | //#include "config.h" 33 | 34 | #include "utf8.h" 35 | #include "utf8internal.h" 36 | 37 | /* 38 | * Decode utf8 string into ucs4 string, 39 | * return number of ucs4 characters decoded 40 | */ 41 | size_t ucs4decode(ucs4 *dst, size_t dst_size, const utf8 *s) 42 | { 43 | ucs4 v, *d = dst; 44 | 45 | if (s) while (*s) { 46 | if (dst_size == 0) 47 | break; 48 | if (IS_UTF8_S1(s)) 49 | v = UCS4_S1(s), s += 1; 50 | else if (IS_UTF8_S2(s)) 51 | v = UCS4_S2(s), s += 2; 52 | else if (IS_UTF8_S3(s)) 53 | v = UCS4_S3(s), s += 3; 54 | else if (IS_UTF8_S4(s)) 55 | v = UCS4_S4(s), s += 4; 56 | else if (IS_UTF8_S5(s)) 57 | v = UCS4_S5(s), s += 5; 58 | else if (IS_UTF8_S6(s)) 59 | v = UCS4_S6(s), s += 6; 60 | else { 61 | s++; 62 | continue; /* skip illegal characters */ 63 | } 64 | *d++ = v; 65 | dst_size--; 66 | }; 67 | 68 | if (dst_size) 69 | *d = 0; 70 | 71 | return d - dst; 72 | } 73 | 74 | /* 75 | * Encode ucs4 string into utf8 string, 76 | * return number of utf8 bytes encoded including final zero 77 | * 78 | * 'quote' may contain an optional quoting table containing 79 | * non-zero for all ASCII characters to quote 80 | * 81 | */ 82 | size_t ucs4encode(utf8 *dst, const ucs4 *s, size_t n, const char quote[128]) 83 | { 84 | utf8 *d = dst; 85 | ucs4 c; 86 | 87 | if (s) while (n-- > 0) { 88 | c = *s++; 89 | 90 | if (IS_UCS4_1(c)) { 91 | if (quote && quote[c]) { 92 | UTF8_S2(d, c); 93 | d += 2; 94 | } 95 | else { 96 | if (!c) /* zero must be represented as UTF8_2 */ 97 | break; 98 | UTF8_S1(d, c); 99 | d += 1; 100 | } 101 | } 102 | else if (IS_UCS4_2(c)) { 103 | UTF8_S2(d, c); 104 | d += 2; 105 | } 106 | else if (IS_UCS4_3(c)) { 107 | UTF8_S3(d, c); 108 | d += 3; 109 | } 110 | else if (IS_UCS4_4(c)) { 111 | UTF8_S4(d, c); 112 | d += 4; 113 | } 114 | else if (IS_UCS4_5(c)) { 115 | UTF8_S5(d, c); 116 | d += 5; 117 | } 118 | else if (IS_UCS4_6(c)) { 119 | UTF8_S6(d, c); 120 | d += 6; 121 | } 122 | else { 123 | /* skip illegal (negative) characters */ 124 | } 125 | } 126 | 127 | *d++ = 0; 128 | return d - dst; 129 | } 130 | 131 | /* 132 | * Length of UCS4 string decoded from UTF8 133 | */ 134 | size_t ucs4declen(const utf8 *s) 135 | { 136 | size_t len = 0; 137 | size_t errors = 0; /* errors */ 138 | 139 | UTF8_ANALYZE(s, len, len, len, len, errors); 140 | 141 | if (errors) 142 | return 0; 143 | 144 | return len; 145 | } 146 | 147 | /* 148 | * Length of UTF8 encoding of a UCS4 string, including final zero 149 | */ 150 | size_t ucs4enclen(const ucs4 *s, size_t n, const char quote[128]) 151 | { 152 | size_t len = 1; 153 | ucs4 c; 154 | 155 | while (n-- > 0) { 156 | c = *s++; 157 | if (c < 0x80u) 158 | if (quote && quote[c]) 159 | len += 2; 160 | else { 161 | if (!c) break; 162 | len += 1; 163 | } 164 | else if (c < 0x800u) 165 | len += 2; 166 | else if (c < 0x10000u) 167 | len += 3; 168 | else if (c < 0x200000u) 169 | len += 4; 170 | else if (c < 0x4000000u) 171 | len += 5; 172 | else if (c < 0x80000000u) 173 | len += 6; 174 | } 175 | 176 | return len; 177 | } 178 | 179 | /* 180 | * Length of UCS4 string (number of non-zero UCS4 characters before zero) 181 | */ 182 | size_t ucs4len(ucs4 const *s) 183 | { 184 | size_t len = 0; 185 | 186 | if (s) while (*s++) 187 | len++; 188 | 189 | return len; 190 | } 191 | 192 | /* 193 | * Compare UCS4 string 194 | */ 195 | int ucs4cmp(ucs4 const *s1, ucs4 const *s2) 196 | { 197 | int retval; 198 | 199 | while ((retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 200 | ; 201 | 202 | return retval; 203 | } 204 | 205 | /* 206 | * Compare UCS4 string prefix 207 | */ 208 | int ucs4ncmp(ucs4 const *s1, ucs4 const *s2, size_t n) 209 | { 210 | int retval = 0; 211 | 212 | while (n-- > 0 && (retval = (*s1 - *s2)) && (*s1++) && (*s2++)) 213 | ; 214 | 215 | return retval; 216 | } 217 | -------------------------------------------------------------------------------- /source/basekit/source/utf8.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | /**@CFILE utf8.c 26 | * 27 | * utf8 string handling. 28 | * 29 | * @author Pekka Pessi 30 | * 31 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 32 | */ 33 | 34 | //#include "config.h" 35 | 36 | #include "utf8.h" 37 | #include "utf8internal.h" 38 | 39 | #ifndef _WIN32 40 | #include 41 | #endif 42 | 43 | /** Width of an UTF8 character cell (1, 2 or 4 bytes) */ 44 | size_t utf8_width(const utf8 *s) 45 | { 46 | size_t w8 = 0, w16 = 0, w32 = 0; 47 | size_t errors = 0; /* errors */ 48 | 49 | UTF8_ANALYZE(s, w8, w8, w16, w32, errors); 50 | 51 | if (errors) 52 | return 0; 53 | 54 | return w32 ? 4 : (w16 ? 2 : 1); 55 | } 56 | 57 | /** Convert UTF8 string @a s to ISO-Latin-1 string @a dst. */ 58 | size_t ucs18decode(char *dst, size_t dst_size, const utf8 *s) 59 | { 60 | #ifndef _WIN32 61 | assert(!"implemented"); 62 | #endif 63 | return 0; 64 | } 65 | 66 | /** Convert ISO-Latin-1 string @a s to UTF8 string in @a dst. */ 67 | size_t ucs1encode(utf8 *dst, const ucs1 *s, size_t n, const char quote[128]) 68 | { 69 | #ifndef _WIN32 70 | assert(!"implemented"); 71 | #endif 72 | return 0; 73 | } 74 | 75 | /** Calculate number of characters in UTF8 string @a s. */ 76 | size_t ucs1declen(const utf8 *s) 77 | { 78 | #ifndef _WIN32 79 | assert(!"implemented"); 80 | #endif 81 | return 0; 82 | } 83 | 84 | /** Calculate length of UTF8 encoding of string @a s. */ 85 | size_t ucs1enclen(const ucs1 *s, size_t n, const char quote[128]) 86 | { 87 | #ifndef _WIN32 88 | assert(!"implemented"); 89 | #endif 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /source/basekit/source/utf8internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Sofia-SIP package 3 | * 4 | * Copyright (C) 2005 Nokia Corporation. 5 | * 6 | * Contact: Pekka Pessi 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License 10 | * as published by the Free Software Foundation; either version 2.1 of 11 | * the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | * 23 | */ 24 | 25 | #ifndef UTF8INTERNAL_H 26 | #define UTF8INTERNAL_H 27 | 28 | /**@IFILE utf8internal.h 29 | * UTF-8 macros. 30 | * 31 | * @author Pekka Pessi 32 | * 33 | * @date Created: Tue Apr 21 15:32:02 1998 pessi 34 | */ 35 | 36 | #define UTF8_ANALYZE(s, ascii, latin1, ucs2, ucs4, errors) \ 37 | do { \ 38 | if (s) while (*s) { \ 39 | utf8 c = *s++; \ 40 | if (IS_UTF8_1(c)) \ 41 | ascii++; \ 42 | else if (IS_UTF8_I(c)) { \ 43 | if (IS_UTF8_X(s[0])) \ 44 | latin1++, s++; \ 45 | else \ 46 | errors++; \ 47 | } \ 48 | else if (IS_UTF8_2(c)) { \ 49 | if (IS_UTF8_X(s[0])) \ 50 | ucs2++, s++; \ 51 | else \ 52 | errors++; \ 53 | } \ 54 | else if (IS_UTF8_3(c)) { \ 55 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1])) \ 56 | ucs2++, s++, s++; \ 57 | else \ 58 | errors++; \ 59 | } \ 60 | else if (IS_UTF8_4(c)) { \ 61 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1]) && IS_UTF8_X(s[2])) \ 62 | ucs4++, s++, s++, s++; \ 63 | else \ 64 | errors++; \ 65 | } \ 66 | else if (IS_UTF8_5(c)) { \ 67 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1]) && \ 68 | IS_UTF8_X(s[2]) && IS_UTF8_X(s[3])) \ 69 | ucs4++, s++, s++, s++, s++; \ 70 | else \ 71 | errors++; \ 72 | } \ 73 | else if (IS_UTF8_6(c)) { \ 74 | if (IS_UTF8_X(s[0]) && IS_UTF8_X(s[1]) && \ 75 | IS_UTF8_X(s[2]) && IS_UTF8_X(s[3]) && IS_UTF8_X(s[4])) \ 76 | ucs4++, s++, s++, s++, s++, s++; \ 77 | else \ 78 | errors++; \ 79 | } \ 80 | else \ 81 | errors++; \ 82 | } \ 83 | } while(0) 84 | 85 | #endif /* UTF8INTERNAL_H */ 86 | -------------------------------------------------------------------------------- /source/httpserver/HttpRequest.c: -------------------------------------------------------------------------------- 1 | #include "HttpRequest.h" 2 | #include "Log.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "HttpServer.h" 16 | 17 | 18 | void Datum_decodeUri(Datum *self) 19 | { 20 | char *k = evhttp_decode_uri(Datum_data(self)); 21 | Datum_setCString_(self, k); 22 | free(k); 23 | } 24 | 25 | void Datum_encodeUri(Datum *self) 26 | { 27 | char *k = evhttp_encode_uri(Datum_data(self)); 28 | Datum_setCString_(self, k); 29 | free(k); 30 | } 31 | 32 | Datum *Datum_asUriEncoded(Datum *self) 33 | { 34 | char *k = evhttp_encode_uri(Datum_data(self)); 35 | Datum *d = Datum_poolNewWithCString_(k); 36 | free(k); 37 | return d; 38 | } 39 | 40 | HttpRequest *HttpRequest_new(void) 41 | { 42 | HttpRequest *self = calloc(1, sizeof(HttpRequest)); 43 | self->post = Datum_new(); 44 | self->uriPath = Datum_new(); 45 | 46 | self->query = CHash_new(); 47 | CHash_setEqualFunc_(self->query, (CHashEqualFunc *)Datum_equals_); 48 | CHash_setHash1Func_(self->query, (CHashHashFunc *)Datum_hash1); 49 | CHash_setHash2Func_(self->query, (CHashHashFunc *)Datum_hash2); 50 | 51 | self->emptyDatum = Datum_new(); 52 | 53 | return self; 54 | } 55 | 56 | void HttpRequest_free(HttpRequest *self) 57 | { 58 | Datum_free(self->post); 59 | Datum_free(self->uriPath); 60 | CHash_free(self->query); 61 | Datum_free(self->emptyDatum); 62 | free(self); 63 | } 64 | 65 | void HttpRequest_parseUri_(HttpRequest *self, const char *uri) 66 | { 67 | int index; 68 | Datum *uriDatum = Datum_poolNew(); 69 | Datum_setCString_(uriDatum, uri); 70 | 71 | //if (self->debug) { Log_Printf_("request: %s\n", uri); } 72 | 73 | CHash_clear(self->query); 74 | 75 | Datum_setSize_(self->uriPath, 0); 76 | index = Datum_from_beforeChar_into_(uriDatum, 1, '?', self->uriPath); 77 | Datum_decodeUri(self->uriPath); 78 | 79 | for (;;) 80 | { 81 | Datum *key = Datum_poolNew(); 82 | Datum *value = Datum_poolNew(); 83 | 84 | index = Datum_from_beforeChar_into_(uriDatum, index + 1, '=', key); 85 | Datum_decodeUri(key); 86 | Datum_nullTerminate(key); 87 | if (Datum_size(key) == 0) break; 88 | 89 | index = Datum_from_beforeChar_into_(uriDatum, index + 1, '&', value); 90 | Datum_decodeUri(value); 91 | Datum_nullTerminate(value); 92 | 93 | CHash_at_put_(self->query, key, value); 94 | if (Datum_size(value) == 0) break; 95 | } 96 | } 97 | 98 | Datum *HttpRequest_uriPath(HttpRequest *self) 99 | { 100 | return self->uriPath; 101 | } 102 | 103 | Datum *HttpRequest_queryValue_(HttpRequest *self, const char *key) 104 | { 105 | Datum *value = CHash_atString_(self->query, key); 106 | return value ? value : self->emptyDatum; 107 | } 108 | 109 | void HttpRequest_readPostData(HttpRequest *self) 110 | { 111 | struct evbuffer *evb = self->request->input_buffer; 112 | Datum_setData_size_(self->post, (const char *)EVBUFFER_DATA(evb), EVBUFFER_LENGTH(evb)); 113 | } 114 | 115 | Datum *HttpRequest_postData(HttpRequest *self) 116 | { 117 | return self->post; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /source/httpserver/HttpRequest.h: -------------------------------------------------------------------------------- 1 | #ifndef HttpRequest_DEFINED 2 | #define HttpRequest_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include "CHash.h" 15 | #include "Datum.h" 16 | 17 | #define HTTP_SERVERERROR 500 18 | #define HTTP_SERVERERROR_MESSAGE "Internal Server Error" 19 | #define HTTP_OK_MESSAGE "OK" 20 | 21 | typedef void (HttpRequestRequestCallback)(void *); 22 | void Datum_encodeUri(Datum *self); 23 | Datum *Datum_asUriEncoded(Datum *self); 24 | 25 | typedef struct 26 | { 27 | struct evhttp_request *request; // doesn't own this 28 | Datum *uriPath; 29 | Datum *post; 30 | CHash *query; 31 | Datum *error; 32 | Datum *emptyDatum; 33 | HttpRequestRequestCallback *requestCallback; 34 | } HttpRequest; 35 | 36 | HttpRequest *HttpRequest_new(void); 37 | void HttpRequest_free(HttpRequest *self); 38 | 39 | Datum *HttpRequest_uriPath(HttpRequest *self); 40 | void HttpRequest_parseUri_(HttpRequest *self, const char *uri); 41 | 42 | void HttpRequest_setDelegate_(HttpRequest *self, void *d); 43 | void HttpRequest_setRequestCallback_(HttpRequest *self, HttpRequestRequestCallback *f); 44 | 45 | Datum *HttpRequest_queryValue_(HttpRequest *self, const char *key); 46 | 47 | void HttpRequest_readPostData(HttpRequest *self); 48 | Datum *HttpRequest_postData(HttpRequest *self); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | #endif 54 | -------------------------------------------------------------------------------- /source/httpserver/HttpResponse.c: -------------------------------------------------------------------------------- 1 | #include "HttpResponse.h" 2 | #include "HttpServer.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | HttpResponse *HttpResponse_new(void) 17 | { 18 | HttpResponse *self = calloc(1, sizeof(HttpResponse)); 19 | self->content = Datum_new(); 20 | self->callback = Datum_new(); 21 | return self; 22 | } 23 | 24 | void HttpResponse_free(HttpResponse *self) 25 | { 26 | Datum_free(self->content); 27 | Datum_free(self->callback); 28 | free(self); 29 | } 30 | 31 | void HttpResponse_setContentType_(HttpResponse *self, const char *v) 32 | { 33 | HttpResponse_setHeader_to_(self, "Content-Type", v); 34 | } 35 | 36 | void HttpResponse_setHeader_to_(HttpResponse *self, const char *k, const char *v) 37 | { 38 | evhttp_remove_header(self->request->output_headers, k); 39 | evhttp_add_header(self->request->output_headers, k, v); 40 | } 41 | 42 | void HttpResponse_setCookie_(HttpResponse *self, Datum *cookie) 43 | { 44 | HttpResponse_setHeader_to_(self, "Content-Type", Datum_data(cookie)); 45 | } 46 | 47 | void HttpResponse_setCallback_(HttpResponse *self, Datum *c) { 48 | Datum_copy_(self->callback, c); 49 | } 50 | 51 | void HttpResponse_setContent_(HttpResponse *self, Datum *d) 52 | { 53 | Datum_copy_(self->content, d); 54 | } 55 | 56 | void HttpResponse_setContentCString_(HttpResponse *self, const char *s) 57 | { 58 | Datum_setCString_(self->content, s); 59 | } 60 | 61 | void HttpResponse_appendContent_(HttpResponse *self, Datum *d) 62 | { 63 | Datum_append_(self->content, d); 64 | } 65 | 66 | void HttpResponse_appendContentCString_(HttpResponse *self, const char *s) 67 | { 68 | Datum_appendCString_(self->content, s); 69 | } 70 | 71 | Datum *HttpResponse_content(HttpResponse *self) 72 | { 73 | return self->content; 74 | } 75 | 76 | void HttpResponse_setStatusCode_(HttpResponse *self, int statusCode) 77 | { 78 | self->statusCode = statusCode; 79 | } 80 | 81 | int HttpResponse_statusCode(HttpResponse *self) 82 | { 83 | return self->statusCode; 84 | } 85 | 86 | void HttpResponse_clear(HttpResponse *self) 87 | { 88 | self->statusCode = 200; 89 | //Datum_clear(self->cookie); 90 | Datum_clear(self->content); 91 | } 92 | 93 | -------------------------------------------------------------------------------- /source/httpserver/HttpResponse.h: -------------------------------------------------------------------------------- 1 | #ifndef HttpResponse_DEFINED 2 | #define HttpResponse_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include "Datum.h" 11 | 12 | typedef struct 13 | { 14 | struct evhttp_request *request; // doesn't own this 15 | int statusCode; 16 | Datum *content; 17 | Datum *callback; // used for JSONP support 18 | } HttpResponse; 19 | 20 | HttpResponse *HttpResponse_new(void); 21 | void HttpResponse_free(HttpResponse *self); 22 | 23 | void HttpResponse_setContentType_(HttpResponse *self, const char *v); 24 | void HttpResponse_setHeader_to_(HttpResponse *self, const char *k, const char *v); 25 | 26 | void HttpResponse_setContent_(HttpResponse *self, Datum *d); 27 | void HttpResponse_setContentCString_(HttpResponse *self, const char *s); 28 | 29 | void HttpResponse_setCallback_(HttpResponse *self, Datum *c); 30 | 31 | void HttpResponse_appendContent_(HttpResponse *self, Datum *d); 32 | void HttpResponse_appendContentCString_(HttpResponse *self, const char *s); 33 | 34 | Datum *HttpResponse_content(HttpResponse *self); 35 | 36 | void HttpResponse_setStatusCode_(HttpResponse *self, int statusCode); 37 | int HttpResponse_statusCode(HttpResponse *self); 38 | 39 | void HttpResponse_setCookie_(HttpResponse *self, Datum *cookie); 40 | 41 | void HttpResponse_clear(HttpResponse *self); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | #endif 47 | -------------------------------------------------------------------------------- /source/httpserver/HttpServer.c: -------------------------------------------------------------------------------- 1 | #include "HttpServer.h" 2 | #include "Log.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | //#include 10 | #include 11 | #include 12 | //#include 13 | //#include 14 | #include 15 | #include "Pool.h" 16 | #include "PNode.h" 17 | 18 | void *CHash_atString_(CHash *self, const char *s) 19 | { 20 | DATUM_STACKALLOCATED(k, s); 21 | return CHash_at_(self, k); 22 | } 23 | 24 | #define HTTP_SERVERERROR 500 25 | #define HTTP_SERVERERROR_MESSAGE "Internal Server Error" 26 | #define HTTP_OK_MESSAGE "OK" 27 | 28 | HttpServer *HttpServer_new(void) 29 | { 30 | HttpServer *self = calloc(1, sizeof(HttpServer)); 31 | self->httpRequest = HttpRequest_new(); 32 | self->httpResponse = HttpResponse_new(); 33 | self->host = Datum_new(); 34 | return self; 35 | } 36 | 37 | void HttpServer_free(HttpServer *self) 38 | { 39 | HttpRequest_free(self->httpRequest); 40 | HttpResponse_free(self->httpResponse); 41 | Datum_free(self->host); 42 | if (self->httpd) evhttp_free(self->httpd); 43 | free(self); 44 | } 45 | 46 | HttpRequest *HttpServer_request(HttpServer *self) 47 | { 48 | return self->httpRequest; 49 | } 50 | 51 | HttpResponse *HttpServer_response(HttpServer *self) 52 | { 53 | return self->httpResponse; 54 | } 55 | 56 | void HttpServer_setHost_(HttpServer *self, char *host) 57 | { 58 | Datum_setCString_(self->host, host); 59 | } 60 | 61 | Datum *HttpServer_host(HttpServer *self) 62 | { 63 | return self->host; 64 | } 65 | 66 | void HttpServer_setPort_(HttpServer *self, int port) 67 | { 68 | self->port = port; 69 | } 70 | 71 | int HttpServer_port(HttpServer *self) 72 | { 73 | return self->port; 74 | } 75 | 76 | void HttpServer_setDelegate_(HttpServer *self, void *d) 77 | { 78 | self->delegate = d; 79 | } 80 | 81 | void *HttpServer_delegate(HttpServer *self) 82 | { 83 | return self->delegate; 84 | } 85 | 86 | void HttpServer_setRequestCallback_(HttpServer *self, HttpServerRequestCallback *f) 87 | { 88 | self->requestCallback = f; 89 | } 90 | 91 | void HttpServer_setIdleCallback_(HttpServer *self, HttpServerIdleCallback *f) 92 | { 93 | self->idleCallback = f; 94 | } 95 | 96 | 97 | void HttpServer_handleRequest(struct evhttp_request *req, void *arg) 98 | { 99 | HttpServer *self = (HttpServer *)arg; 100 | const char *uri = evhttp_request_uri(req); 101 | struct evbuffer *buf = evbuffer_new(); 102 | 103 | self->gotRequest = 1; 104 | 105 | self->request = req; 106 | self->httpRequest->request = req; 107 | self->httpResponse->request = req; 108 | 109 | HttpRequest_readPostData(self->httpRequest); 110 | HttpResponse_clear(self->httpResponse); 111 | 112 | if (strcmp(uri, "/favicon.ico") == 0) 113 | { 114 | evhttp_send_reply(self->request, HTTP_OK, HTTP_OK_MESSAGE, buf); 115 | } 116 | else 117 | { 118 | HttpRequest_parseUri_(self->httpRequest, uri); 119 | self->requestCallback(self->delegate); 120 | 121 | if (Datum_size(self->httpResponse->callback)) { 122 | evbuffer_add_printf(buf, "%s(%s)", Datum_data(self->httpResponse->callback), Datum_data(HttpResponse_content(self->httpResponse))); 123 | } else { 124 | evbuffer_add_printf(buf, "%s", Datum_data(HttpResponse_content(self->httpResponse))); 125 | } 126 | 127 | if (HttpResponse_statusCode(self->httpResponse) == 200) 128 | { 129 | evhttp_send_reply(self->request, HTTP_OK, HTTP_OK_MESSAGE, buf); 130 | } 131 | else 132 | { 133 | evhttp_send_reply(self->request, HTTP_SERVERERROR, HTTP_SERVERERROR_MESSAGE, buf); 134 | } 135 | } 136 | 137 | evhttp_send_reply_end(self->request); 138 | evbuffer_free(buf); 139 | Datum_poolFreeRefs(); 140 | PNode_poolFreeRefs(); 141 | } 142 | 143 | void HttpServer_run(HttpServer *self) 144 | { 145 | if(self->shutdown) return; 146 | self->shutdown = 0; 147 | 148 | event_init(); 149 | 150 | self->httpd = evhttp_start(Datum_data(self->host), self->port); 151 | 152 | if (!self->httpd) 153 | { 154 | Log_Printf__("evhttp_start failed - is another copy running on port %i or wrong -host ip %s ?\n", self->port, Datum_data(self->host)); 155 | exit(-1); 156 | } 157 | 158 | evhttp_set_timeout(self->httpd, 180); 159 | evhttp_set_gencb(self->httpd, HttpServer_handleRequest, self); 160 | 161 | while (!self->shutdown) 162 | { 163 | if(self->idleCallback) 164 | { 165 | self->gotRequest = 0; 166 | 167 | event_loop(EVLOOP_NONBLOCK); 168 | 169 | if (!self->gotRequest && self->idleCallback) 170 | { 171 | self->idleCallback(self->delegate); 172 | } 173 | } 174 | else 175 | { 176 | event_loop(EVLOOP_ONCE); 177 | } 178 | } 179 | } 180 | 181 | void HttpServer_shutdown(HttpServer *self) 182 | { 183 | self->shutdown = 1; 184 | event_loopbreak(); 185 | } 186 | 187 | -------------------------------------------------------------------------------- /source/httpserver/HttpServer.h: -------------------------------------------------------------------------------- 1 | #ifndef HttpServer_DEFINED 2 | #define HttpServer_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include "HttpRequest.h" 15 | #include "HttpResponse.h" 16 | 17 | typedef void (HttpServerRequestCallback)(void *); 18 | typedef void (HttpServerIdleCallback)(void *); 19 | //typedef void (HttpServerWriteMethod)(void *); 20 | 21 | #define HTTP_SERVERERROR 500 22 | #define HTTP_SERVERERROR_MESSAGE "Internal Server Error" 23 | #define HTTP_OK_MESSAGE "OK" 24 | 25 | typedef struct 26 | { 27 | struct evhttp *httpd; 28 | struct evhttp_request *request; 29 | 30 | Datum *host; 31 | int port; 32 | 33 | void *delegate; 34 | HttpServerRequestCallback *requestCallback; 35 | HttpServerIdleCallback *idleCallback; 36 | 37 | int shutdown; 38 | 39 | HttpRequest *httpRequest; 40 | HttpResponse *httpResponse; 41 | int gotRequest; 42 | } HttpServer; 43 | 44 | void *CHash_atString_(CHash *self, const char *s); 45 | 46 | HttpServer *HttpServer_new(void); 47 | void HttpServer_free(HttpServer *self); 48 | 49 | HttpRequest *HttpServer_request(HttpServer *self); 50 | HttpResponse *HttpServer_response(HttpServer *self); 51 | 52 | void HttpServer_setHost_(HttpServer *self, char *host); 53 | Datum *HttpServer_host(HttpServer *self); 54 | 55 | void HttpServer_setPort_(HttpServer *self, int port); 56 | int HttpServer_port(HttpServer *self); 57 | 58 | void HttpServer_setDelegate_(HttpServer *self, void *d); 59 | void HttpServer_setRequestCallback_(HttpServer *self, HttpServerRequestCallback *f); 60 | void HttpServer_setIdleCallback_(HttpServer *self, HttpServerIdleCallback *f); 61 | 62 | void HttpServer_run(HttpServer *self); 63 | void HttpServer_shutdown(HttpServer *self); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | #endif 69 | -------------------------------------------------------------------------------- /source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "VertexServer.h" 3 | 4 | #define HELP_MESSAGE "See vertexdb --help for more information\n" 5 | #define RAISE_ARG_ERROR(a, argc, message) if (a >= argc) { printf("Wrong arguments count or arguments order for: %s\n%s", message, HELP_MESSAGE); return -1; } 6 | 7 | int main(int argc, char **argv) 8 | { 9 | int a = 1; 10 | 11 | VertexServer *server = VertexServer_new(); 12 | VertexServer_setHardSync_(server, 0); 13 | while (a < argc) 14 | { 15 | if (strcmp(argv[a], "-db") == 0 || strcmp(argv[a], "--database") == 0) 16 | { 17 | a ++; 18 | RAISE_ARG_ERROR(a, argc, argv[a - 1]); 19 | PDB_setPathCString_(server->pdb, argv[a]); 20 | a ++; 21 | } 22 | else if (strcmp(argv[a], "-p") == 0 || strcmp(argv[a], "--port") == 0) 23 | { 24 | a ++; 25 | RAISE_ARG_ERROR(a, argc, argv[a - 1]); 26 | VertexServer_setPort_(server, atoi(argv[a])); 27 | a ++; 28 | } 29 | else if (strcmp(argv[a], "-H") == 0 || strcmp(argv[a], "--host") == 0) 30 | { 31 | a ++; 32 | RAISE_ARG_ERROR(a, argc, argv[a - 1]); 33 | VertexServer_setHost_(server, argv[a]); 34 | a ++; 35 | } 36 | else if (strcmp(argv[a], "-d") == 0 || strcmp(argv[a], "--daemon") == 0) 37 | { 38 | a ++; 39 | VertexServer_setIsDaemon_(server, 1); 40 | } 41 | else if (strcmp(argv[a], "--log") == 0) 42 | { 43 | a ++; 44 | RAISE_ARG_ERROR(a, argc, argv[a - 1]); 45 | VertexServer_setLogPath_(server, argv[a]); 46 | a ++; 47 | } 48 | else if (strcmp(argv[a], "--pid") == 0) 49 | { 50 | a ++; 51 | RAISE_ARG_ERROR(a, argc, argv[a - 1]); 52 | VertexServer_setPidPath_(server, argv[a]); 53 | a ++; 54 | } 55 | else if (strcmp(argv[a], "--debug") == 0) 56 | { 57 | a ++; 58 | VertexServer_setDebug_(server, 1); 59 | } 60 | else if (strcmp(argv[a], "--hardsync") == 0) 61 | { 62 | a ++; 63 | VertexServer_setHardSync_(server, 1); 64 | } 65 | else if (strcmp(argv[a], "--help") == 0 || strcmp(argv[a], "help") == 0 || strcmp(argv[a], "-h") == 0) 66 | { 67 | printf("VertexDB usage:\n" 68 | " --database -db Database file\n" 69 | " --port -p TCP port number to listen on (default: 8080)\n" 70 | " --host -H Network interface to listen (default: 127.0.0.1)\n" 71 | " --daemon -d Run as a daemon\n" 72 | " --log Log file location\n" 73 | " --pid Pid file location\n" 74 | " --debug Be more verbose\n" 75 | " --hardsync Run with hard syncronization\n" 76 | " --help -h Show this help\n" 77 | ); 78 | return 0; 79 | } else { 80 | printf("Weird parametr \"%s\"\n%s", argv[a], HELP_MESSAGE); 81 | a ++; 82 | } 83 | } 84 | 85 | if (server->isDaemon && !server->pidPath) { 86 | printf("--pid is required when running as daemon\n"); 87 | exit(-1); 88 | } 89 | 90 | VertexServer_run(server); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /source/pdb/Datum.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef Datum_DEFINED 3 | #define Datum_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include 10 | #include "Pool.h" 11 | 12 | typedef struct 13 | { 14 | char *data; 15 | size_t size; 16 | } Datum; 17 | 18 | #define DATUM_STACKALLOCATED(name, string) Datum _##name; Datum *name = &_##name; name->data = (char *)string; name->size = strlen(string); 19 | 20 | int Datum_datumCount(void); 21 | Pool *Datum_pool(void); 22 | Datum *Datum_poolNew(void); 23 | Datum *Datum_poolNewWithCString_(const char *s); 24 | Datum *Datum_poolNewWithData_size_(const char *data, size_t size); 25 | void Datum_poolFreeRefs(void); 26 | void Datum_freePool(void); 27 | 28 | Datum *Datum_new(void); 29 | Datum *Datum_newWithCString_(const char *s); 30 | Datum *Datum_clone(Datum *d); 31 | 32 | void Datum_free(Datum *self); 33 | void Datum_setData_size_(Datum *self, const char *data, size_t size); 34 | void Datum_setCString_(Datum *self, const char *s); 35 | void Datum_setSize_(Datum *self, size_t size); 36 | size_t Datum_size(Datum *self); 37 | void Datum_nullTerminate(Datum *self); 38 | 39 | const char *Datum_data(Datum *self); 40 | void Datum_show(Datum *self); 41 | 42 | void Datum_copy_(Datum *self, Datum *other); 43 | void Datum_copy_and_(Datum *self, Datum *other, Datum *other2); 44 | 45 | void Datum_selectPathComponent(Datum *self); 46 | void Datum_selectLastComponent(Datum *self); 47 | 48 | void Datum_append_(Datum *self, Datum *other); 49 | void Datum_appendBytes_size_(Datum *self, const unsigned char *bytes, size_t size); 50 | void Datum_appendQuoted_(Datum *self, Datum *other); 51 | void Datum_appendCString_(Datum *self, const char *s); 52 | void Datum_appendLong_(Datum *self, long n); 53 | 54 | int Datum_equals_(Datum *self, Datum *other); 55 | int Datum_equalsCString_(Datum *self, const char *s); 56 | int Datum_compare_(Datum *self, Datum *other); 57 | 58 | unsigned int Datum_hash1(Datum *self); 59 | unsigned int Datum_hash2(Datum *self); 60 | 61 | int Datum_beginsWith_(Datum *self, Datum *other); 62 | int Datum_beginsWithCString_(Datum *self, const char *s); 63 | 64 | int Datum_isBeginningOfCString_(Datum *self, const char *s); 65 | 66 | void Datum_clear(Datum *self); 67 | int Datum_isEmpty(Datum *self); 68 | 69 | void Datum_makeIdOfLength_(Datum *self, int length); 70 | void Datum_makePidOfLength_(Datum *self, int length); 71 | void Datum_makePid32(Datum *self); 72 | void Datum_makePid64(Datum *self); 73 | void Datum_fromLong_(Datum *self, long n); 74 | int Datum_asInt(Datum *self); 75 | long Datum_asLong(Datum *self); 76 | 77 | int Datum_sepOnChars_with_(Datum *self, const char *s, Datum *other); 78 | int Datum_containsChar_(Datum *self, char c); 79 | int Datum_charAt_(Datum *self, unsigned int index); // returns -1 for invalid indexes 80 | int Datum_at_put_(Datum *self, unsigned int index, char c); // returns -1 for invalid indexes 81 | 82 | void Datum_clipLastPathComponent(Datum *self); 83 | 84 | int Datum_from_beforeChar_into_(Datum *self, unsigned int start, char c, Datum *other); 85 | //int Datum_indexOfChar_(Datum *self, char c); 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | #endif 91 | -------------------------------------------------------------------------------- /source/pdb/File.c: -------------------------------------------------------------------------------- 1 | #include "File.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int File_System(Datum *cmd) 7 | { 8 | //Log_Printf_("system: %s\n", Datum_data(cmd)); 9 | int result = system(Datum_data(cmd)); 10 | return result; 11 | } 12 | 13 | File *File_new(void) 14 | { 15 | File *self = calloc(1, sizeof(File)); 16 | self->path = Datum_new(); 17 | return self; 18 | } 19 | 20 | File *File_with_(const char *path) 21 | { 22 | File *aFile = File_new(); 23 | File_setPathCString_(aFile, path); 24 | return aFile; 25 | } 26 | 27 | void File_free(File *self) 28 | { 29 | Datum_free(self->path); 30 | free(self); 31 | } 32 | 33 | void File_setPathCString_(File *self, const char *path) 34 | { 35 | Datum_setCString_(self->path, path); 36 | } 37 | 38 | const char *File_pathCString(File *self) 39 | { 40 | return Datum_data(self->path); 41 | } 42 | 43 | void File_setPath_(File *self, Datum *path) 44 | { 45 | Datum_copy_(self->path, path); 46 | } 47 | 48 | Datum *File_path(File *self) 49 | { 50 | return self->path; 51 | } 52 | 53 | void File_appendToPath_(File *self, Datum *path) 54 | { 55 | Datum_append_(self->path, path); 56 | } 57 | 58 | void File_appendToPathCString_(File *self, const char *path) 59 | { 60 | Datum_appendCString_(self->path, path); 61 | } 62 | 63 | void File_fatalError_(File *self, char *s) 64 | { 65 | //Log_Printf__("File error: %s\n", s); 66 | exit(-1); 67 | } 68 | 69 | int File_exists(File *self) 70 | { 71 | FILE *fp = fopen(Datum_data(self->path), "r"); 72 | if (fp) { fclose(fp); return 1; } 73 | return 0; 74 | } 75 | 76 | int File_create(File *self) 77 | { 78 | FILE *fp = fopen(Datum_data(self->path), "w"); 79 | 80 | if(!fp) 81 | { 82 | Log_Printf_("File: unable to create file '%s'\n", Datum_data(self->path)); 83 | return -1; 84 | } 85 | 86 | fclose(fp); 87 | 88 | return 0; 89 | } 90 | 91 | int File_remove(File *self) 92 | { 93 | int result; 94 | Datum *cmd = Datum_newWithCString_("rm "); 95 | Datum_append_(cmd, self->path); 96 | result = File_System(cmd); 97 | Datum_free(cmd); 98 | return result; 99 | } 100 | 101 | int File_moveTo_(File *self, File *other) 102 | { 103 | int result; 104 | Datum *cmd = Datum_newWithCString_("mv "); 105 | Datum_append_(cmd, self->path); 106 | Datum_appendCString_(cmd, " "); 107 | Datum_append_(cmd, File_path(other)); 108 | result = File_System(cmd); 109 | Datum_free(cmd); 110 | return result; 111 | } 112 | 113 | int File_copyTo_(File *self, File *other) 114 | { 115 | int result; 116 | Datum *cmd = Datum_newWithCString_("cp "); 117 | Datum_append_(cmd, self->path); 118 | Datum_appendCString_(cmd, " "); 119 | Datum_append_(cmd, File_path(other)); 120 | result = File_System(cmd); 121 | Datum_free(cmd); 122 | return result; 123 | } 124 | 125 | int File_symbolicallyLinkTo_(File *self, File *other) 126 | { 127 | int result; 128 | Datum *cmd = Datum_newWithCString_("ln -sf "); 129 | Datum_append_(cmd, self->path); 130 | Datum_appendCString_(cmd, " "); 131 | Datum_append_(cmd, File_path(other)); 132 | result = File_System(cmd); 133 | Datum_free(cmd); 134 | return result; 135 | } 136 | 137 | int File_createDirectory(File *self) 138 | { 139 | int result; 140 | Datum *cmd = Datum_newWithCString_("mkdir -p "); 141 | Datum_append_(cmd, self->path); 142 | result = File_System(cmd); 143 | Datum_free(cmd); 144 | return result; 145 | } 146 | -------------------------------------------------------------------------------- /source/pdb/File.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef File_DEFINED 3 | #define File_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include 10 | #include "Datum.h" 11 | #include "Log.h" 12 | 13 | typedef struct 14 | { 15 | Datum *path; 16 | } File; 17 | 18 | File *File_new(void); 19 | File *File_with_(const char *path); 20 | void File_free(File *self); 21 | 22 | void File_setPathCString_(File *self, const char *path); 23 | const char *File_pathCString(File *self); 24 | 25 | void File_setPath_(File *self, Datum *path); 26 | Datum *File_path(File *self); 27 | 28 | void File_appendToPath_(File *self, Datum *path); 29 | void File_appendToPathCString_(File *self, const char *path); 30 | 31 | int File_exists(File *self); 32 | int File_create(File *self); 33 | int File_remove(File *self); 34 | 35 | int File_moveTo_(File *self, File *other); 36 | int File_copyTo_(File *self, File *other); 37 | int File_symbolicallyLinkTo_(File *self, File *other); 38 | 39 | int File_createDirectory(File *self); 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | #endif 45 | -------------------------------------------------------------------------------- /source/pdb/Log.c: -------------------------------------------------------------------------------- 1 | #define LOG_C 2 | #include "Log.h" 3 | #undef LOG_C 4 | /* 5 | #include 6 | #include 7 | #include 8 | #include 9 | */ 10 | #include 11 | #include 12 | 13 | static char timeString[1024]; 14 | 15 | static Log *globalLog = 0x0; 16 | 17 | Log *Log_sharedLog(void) 18 | { 19 | if(!globalLog) 20 | { 21 | globalLog = calloc(1, sizeof(Log)); 22 | globalLog->file = stderr; 23 | } 24 | 25 | return globalLog; 26 | } 27 | 28 | const char *Log_TimeString(void) 29 | { 30 | time_t t = time(NULL); 31 | struct tm *tt = localtime(&t); 32 | strftime(timeString, 128, "%Y-%m-%d %H:%M:%S", tt); 33 | return timeString; 34 | } 35 | 36 | void Log_setPath_(const char *path) 37 | { 38 | Log_sharedLog()->path = path; 39 | } 40 | 41 | const char *Log_path(void) 42 | { 43 | return Log_sharedLog()->path; 44 | } 45 | 46 | int Log_close(void) 47 | { 48 | if(Log_sharedLog()->file && Log_sharedLog()->file != stderr) 49 | { 50 | return fclose(Log_sharedLog()->file); 51 | } 52 | else 53 | { 54 | return 0; 55 | } 56 | } 57 | 58 | int Log_open(void) 59 | { 60 | const char *path = Log_sharedLog()->path; 61 | Log_close(); 62 | 63 | if(path == 0x0) 64 | { 65 | Log_Printf("Logging to stderr\n"); 66 | return 0; 67 | } 68 | 69 | { 70 | FILE *file = fopen(path, "a"); 71 | 72 | if(file) 73 | { 74 | Log_sharedLog()->file = file; 75 | Log_Printf_("Logging to %s\n", path); 76 | return 0; 77 | } 78 | else 79 | { 80 | Log_Printf_("Unable to open log file for writing: %s\n", path); 81 | return 1; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /source/pdb/Log.h: -------------------------------------------------------------------------------- 1 | #ifndef Log_DEFINED 2 | #define Log_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | typedef struct 11 | { 12 | const char *path; 13 | FILE *file; 14 | } Log; 15 | 16 | Log *Log_sharedLog(void); 17 | const char *Log_TimeString(void); 18 | void Log_setPath_(const char *path); 19 | const char *Log_path(void); 20 | int Log_close(void); 21 | int Log_open(void); 22 | 23 | #define Log_Printf(s) fputs(Log_TimeString(), Log_sharedLog()->file); fprintf(Log_sharedLog()->file, ": "); fprintf(Log_sharedLog()->file, s); fflush(Log_sharedLog()->file); 24 | #define Log_Printf_(s, a1) fputs(Log_TimeString(), Log_sharedLog()->file); fprintf(Log_sharedLog()->file, ": "); fprintf(Log_sharedLog()->file, s, a1); fflush(Log_sharedLog()->file); 25 | #define Log_Printf__(s, a1, a2) fputs(Log_TimeString(), Log_sharedLog()->file); fprintf(Log_sharedLog()->file, ": "); fprintf(Log_sharedLog()->file, s, a1, a2); fflush(Log_sharedLog()->file); 26 | #define Log_Printf___(s, a1, a2, a3) fputs(Log_TimeString(), Log_sharedLog()->file); fprintf(Log_sharedLog()->file, ": "); fprintf(Log_sharedLog()->file, s, a1, a2, a3); fflush(Log_sharedLog()->file); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | #endif 32 | -------------------------------------------------------------------------------- /source/pdb/PCollector.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PCollector_DEFINED 3 | #define PCollector_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include 10 | #include "PDB.h" 11 | 12 | typedef struct 13 | { 14 | PDB *in; 15 | PNode *inNode; 16 | 17 | PDB *out; 18 | PNode *outNode; 19 | 20 | CHash *savedPids; 21 | List *saveQueue; 22 | size_t markCount; 23 | double maxStepTime; 24 | 25 | time_t beginTime; 26 | uint64_t beginKeyCount; 27 | 28 | int isCollecting; 29 | } PCollector; 30 | 31 | PCollector *PCollector_new(void); 32 | void PCollector_free(PCollector *self); 33 | void PCollector_setIn_(PCollector *self, void *pdb); 34 | 35 | void PCollector_begin(PCollector *self); 36 | void PCollector_step(PCollector *self); 37 | long PCollector_complete(PCollector *self); 38 | //void PCollector_cancel(PCollector *self); 39 | 40 | int PCollector_shouldUpdateKey_(PCollector *self, const char *k, int ksize); 41 | int PCollector_hasSaved_(PCollector *self, long pid); 42 | void PCollector_addToSaveQueue_(PCollector *self, long pid); 43 | void PCollector_markPid_(PCollector *self, long pid); 44 | int PCollector_isCollecting(PCollector *self); 45 | 46 | void PCollector_showStatus(PCollector *self); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | #endif 52 | -------------------------------------------------------------------------------- /source/pdb/PDB.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PDB_DEFINED 3 | #define PDB_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include 10 | #include "PNode.h" 11 | #include "List.h" 12 | #include "File.h" 13 | #include "Common.h" 14 | #include "CHash.h" 15 | #include "Yajl_extras.h" 16 | #include "Store.h" 17 | //#include "PCollector.h" 18 | //#include "PBackup.h" 19 | 20 | typedef void (PDBPutCallback)(void *, const char *k, int ksize, const char *v, int vsize); 21 | typedef void (PDBCatCallback)(void *, const char *k, int ksize, const char *v, int vsize); 22 | typedef void (PDBRemoveCallback)(void *, const char *k, int ksize); 23 | 24 | typedef struct 25 | { 26 | Store *store; 27 | File *dbFile; 28 | int inTransaction; 29 | //Datum *currentUser; 30 | yajl_gen yajl; 31 | int isClosing; 32 | int hardSync; 33 | void *collector; 34 | 35 | // callbacks 36 | void *delegate; 37 | PDBPutCallback *putCallback; 38 | PDBCatCallback *catCallback; 39 | PDBRemoveCallback *removeCallback; 40 | } PDB; 41 | 42 | PDB *PDB_new(void); 43 | void PDB_setYajl_(PDB *self, yajl_gen yajl); 44 | void PDB_free(PDB *self); 45 | 46 | // callbacks 47 | void PDB_setDelegate_(PDB *self, void *d); 48 | void PDB_setPutCallback_(PDB *self, PDBPutCallback *func); 49 | void PDB_setCatCallback_(PDB *self, PDBCatCallback *func); 50 | void PDB_setRemoveCallback_(PDB *self, PDBRemoveCallback *func); 51 | 52 | // nodes ------------- 53 | PNode *PDB_allocNode(PDB *self); 54 | PNode *PDB_newNode(PDB *self); 55 | 56 | // open/close ------------ 57 | void PDB_setPathCString_(PDB *self, const char *path); 58 | void PDB_setHardSync_(PDB *self, int aBool); 59 | int PDB_open(PDB *self); 60 | void PDB_close(PDB *self); 61 | 62 | // backups ------------ 63 | void PDB_setUseBackups_(PDB *self, int aBool); 64 | int PDB_backup(PDB *self); 65 | 66 | // transactions ------------ 67 | void PDB_willWrite(PDB *self); // private to PDB and PNode 68 | void PDB_begin(PDB *self); 69 | void PDB_abort(PDB *self); 70 | void PDB_rawCommit(PDB *self); // private 71 | void PDB_commit(PDB *self); 72 | 73 | // read/write ------------ 74 | void *PDB_at_(PDB *self, const char *k, int ksize, int *vsize); 75 | int PDB_at_put_(PDB *self, const char *k, int ksize, const char *v, int vsize); 76 | int PDB_at_cat_(PDB *self, const char *k, int ksize, const char *v, int vsize); 77 | int PDB_removeAt_(PDB *self, const char *k, int ksize); 78 | 79 | // helpers ------------ 80 | long PDB_sizeInMB(PDB *self); 81 | uint64_t PDB_numberOfKeys(PDB *self); 82 | int PDB_syncSizes(PDB *self); 83 | 84 | void PDB_beginCollectGarbage(PDB *self); 85 | int PDB_isCollecting(PDB *self); 86 | void PDB_collectStep(PDB *self); 87 | 88 | void PDB_moveTo_(PDB *self, PDB *other); 89 | 90 | void PDB_remove(PDB *self); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | #endif 96 | -------------------------------------------------------------------------------- /source/pdb/PNode.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef Pnode_DEFINED 3 | #define Pnode_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "Store.h" 14 | #include 15 | #include 16 | #include 17 | #include "Datum.h" 18 | #include "PQuery.h" 19 | #include "Yajl_extras.h" 20 | #include "Pool.h" 21 | 22 | typedef struct 23 | { 24 | void *pdb; 25 | StoreCursor *storeCursor; 26 | 27 | Datum *pid; 28 | Datum *pidPath; 29 | Datum *keyPath; 30 | 31 | Datum *sizePath; 32 | Datum *parentPid; 33 | PQuery *query; 34 | 35 | yajl_gen yajl; 36 | } PNode; 37 | 38 | typedef int (PNodeOp)(PNode *, Datum *); 39 | 40 | 41 | // creation and setup 42 | Pool *PNode_pool(void); 43 | PNode *PNode_poolNew(void); 44 | PNode *PNode_new(void); 45 | void PNode_poolFreeRefs(void); 46 | void PNode_freePool(void); 47 | 48 | void PNode_setYajl_(PNode *self, yajl_gen y); 49 | void PNode_setPdb_(PNode *self, void *pdb); 50 | void PNode_free(PNode *self); 51 | void PNode_clear(PNode *self); 52 | 53 | // open/close 54 | void PNode_open(PNode *self); 55 | void PNode_close(PNode *self); 56 | void *PNode_pdb(PNode *self); 57 | PQuery *PNode_query(PNode *self); 58 | 59 | // pids 60 | void PNode_setPid_(PNode *self, Datum *pid); 61 | void PNode_setPidLong_(PNode *self, long pid); 62 | void PNode_setPidCString_(PNode *self, const char *pid); 63 | Datum *PNode_pid(PNode *self); 64 | 65 | // at, put, remove 66 | Datum *PNode_at_(PNode *self, Datum *k); 67 | Datum *PNode_atCString_(PNode *self, const char *k); 68 | int PNode_atPut_(PNode *self, Datum *k, Datum *v); 69 | int PNode_atCat_(PNode *self, Datum *k, Datum *v); 70 | int PNode_removeAt_(PNode *self, Datum *k); 71 | void PNode_setToRoot(PNode *self); 72 | 73 | // meta 74 | int PNode_metaAt_put_(PNode *self, Datum *key, Datum *value); 75 | Datum *PNode_metaAt_(PNode *self, Datum *d); 76 | 77 | // size ops 78 | int PNode_setSize_(PNode *self, long s); // PRIVATE !!! 79 | void PNode_setPathsFromPid(PNode *self); 80 | long PNode_size(PNode *self); 81 | int PNode_incrementSize(PNode *self); 82 | int PNode_decrementSize(PNode *self); 83 | long PNode_nodeSizeAtCursor(PNode *self); 84 | 85 | // query enumeration 86 | PQuery *PNode_startQuery(PNode *self); 87 | int PNode_doesExist(PNode *self); 88 | void PNode_first(PNode *self); 89 | void PNode_jump_(PNode *self, Datum *k); 90 | void PNode_jumpToCurrentKey(PNode *self); 91 | int PNode_next(PNode *self); 92 | int PNode_previous(PNode *self); 93 | void PNode_removeAtCursor(PNode *self); 94 | 95 | // set/get key and value 96 | void PNode_setKey_(PNode *self, Datum *v); 97 | Datum *PNode_key(PNode *self); 98 | void PNode_setValue_(PNode *self, Datum *v); 99 | Datum *PNode_value(PNode *self); 100 | 101 | // paths 102 | int PNode_moveToKey_(PNode *self, Datum *key); 103 | int PNode_createMoveToKeyString_(PNode *self, const char *k); 104 | int PNode_createMoveToKey_(PNode *self, Datum *key); 105 | //int PNode_mergeTo_(PNode *self, PNode *destNode, int withKeys); 106 | int PNode_remove(PNode *self); 107 | //Datum *PNode_valueFromDerefKeyToPath_(PNode *self, Datum *derefPath); 108 | int PNode_moveToPathIfExists_(PNode *self, Datum *p); 109 | int PNode_moveToSubpathIfExists_(PNode *self, Datum *p); 110 | int PNode_moveToPath_(PNode *self, Datum *p); 111 | int PNode_moveToPathCString_(PNode *self, const char *p); 112 | //int PNode_moveToSubpathCString_(PNode *self, const char *p); 113 | void PNode_create(PNode *self); 114 | 115 | // garbage collection helpers 116 | long PNode_pidAsLong(PNode *self); 117 | void PNode_mark(PNode *self); 118 | int PNode_takePidFromCursor(PNode *self); // returns 0 on success 119 | int PNode_moveToNextNode(PNode *self); // returns slot count or a negative number on end or error 120 | int PNode_findSize(PNode *self); // returns slot count or a negative number on end or error 121 | int PNode_withId_hasKey_andValue_(PNode *self, Datum *pid, Datum *wk, Datum *wv); 122 | 123 | // query ops 124 | int PNode_op_object(PNode *self, Datum *d); 125 | int PNode_op_sizes(PNode *self, Datum *d); 126 | int PNode_op_count(PNode *self, Datum *d); 127 | int PNode_op_keys(PNode *self, Datum *d); 128 | int PNode_op_pairs(PNode *self, Datum *d); 129 | int PNode_op_values(PNode *self, Datum *d); 130 | int PNode_op_rm(PNode *self, Datum *d); 131 | int PNode_op_html(PNode *self, Datum *d); 132 | int PNode_asHtmlRow(PNode *self, Datum *d); 133 | int PNode_amSeries(PNode *self, Datum *d); 134 | int PNode_amGraphKey_(PNode *self, Datum *title, Datum *graphKey, Datum *d); 135 | 136 | // permissions 137 | Datum *PNode_op_owner(PNode *self); 138 | Datum *PNode_op_public(PNode *self); 139 | 140 | // debugging 141 | void PNode_show(PNode *self); 142 | 143 | #ifdef __cplusplus 144 | } 145 | #endif 146 | #endif 147 | -------------------------------------------------------------------------------- /source/pdb/PQuery.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PQuery_DEFINED 3 | #define PQuery_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | //#include "PDB.h" 10 | #include "Datum.h" 11 | #include "CHash.h" 12 | 13 | //typedef struct PNode PNode; 14 | 15 | typedef struct 16 | { 17 | void *node; 18 | void *tmpNode; 19 | 20 | Datum *id; 21 | Datum *after; 22 | Datum *before; 23 | Datum *whereKey; 24 | Datum *whereValue; 25 | Datum *attribute; 26 | 27 | unsigned int selectCount; 28 | unsigned int selectCountMax; 29 | unsigned int hasFilter; 30 | unsigned int hasRange; 31 | int stepDirection; 32 | int isDone; 33 | } PQuery; 34 | 35 | typedef int (PQueryMethod)(PQuery *); 36 | 37 | PQuery *PQuery_new(void); 38 | void PQuery_free(PQuery *self); 39 | 40 | void PQuery_setNode_(PQuery *self, void *node); 41 | void PQuery_setTmpNode_(PQuery *self, void *node); 42 | void *PQuery_tmpNode(PQuery *self); 43 | 44 | void PQuery_setId_(PQuery *self, Datum *d); 45 | void PQuery_setAfter_(PQuery *self, Datum *d); 46 | void PQuery_setBefore_(PQuery *self, Datum *d); 47 | void PQuery_setWhereKey_(PQuery *self, Datum *d); 48 | void PQuery_setWhereValue_(PQuery *self, Datum *d); 49 | void PQuery_setSelectCountMax_(PQuery *self, unsigned int n); 50 | void PQuery_setAttribute_(PQuery *self, Datum *d); 51 | Datum *PQuery_attribute(PQuery *self); 52 | Datum *PQuery_attributeValue(PQuery *self); 53 | 54 | int PQuery_setup(PQuery *self); 55 | Datum *PQuery_key(PQuery *self); 56 | void PQuery_enumerate(PQuery *self); 57 | int PQuery_stepDirection(PQuery *self); 58 | 59 | int PQuery_cursorMatches(PQuery *self); // private 60 | int PQuery_moveToNextMatch(PQuery *self); // private 61 | int PQuery_isInRange(PQuery *self); // private 62 | 63 | unsigned int PQuery_selectCount(PQuery *self); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | #endif 69 | -------------------------------------------------------------------------------- /source/pdb/Pointer.c: -------------------------------------------------------------------------------- 1 | 2 | #include "Pointer.h" 3 | #include 4 | #include "Hash_murmur.h" 5 | #include "Hash_superfast.h" 6 | 7 | int Pointer_equals_(void *p1, void *p2) 8 | { 9 | return (uintptr_t)p1 == (uintptr_t)p2; 10 | /* 11 | uintptr_t i1 = (uintptr_t)p1; 12 | uintptr_t i2 = (uintptr_t)p2; 13 | if(i1 == i2) return 0; 14 | if(i1 < i2) return 1; 15 | return -1; 16 | */ 17 | } 18 | 19 | unsigned int Pointer_hash1(void *p) 20 | { 21 | return MurmurHash2((const void *)&p, (int)sizeof(void *), 0) | 0x1; // odd 22 | } 23 | 24 | unsigned int Pointer_hash2(void *p) 25 | { 26 | return SuperFastHash((const char *)&p, (int)sizeof(void *)) << 1; // even 27 | } 28 | 29 | -------------------------------------------------------------------------------- /source/pdb/Pointer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef POINTER_DEFINED 3 | #define POINTER_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | int Pointer_equals_(void *p1, void *p2); 10 | unsigned int Pointer_hash1(void *p); 11 | unsigned int Pointer_hash2(void *p); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /source/pdb/Pool.c: -------------------------------------------------------------------------------- 1 | #define Pool_C 2 | #include "Pool.h" 3 | #undef Pool_C 4 | 5 | #include 6 | #include 7 | 8 | Pool *Pool_new(void) 9 | { 10 | Pool *self = calloc(1, sizeof(Pool)); 11 | self->refs = List_new(); 12 | self->recycled = List_new(); 13 | return self; 14 | } 15 | 16 | void Pool_free(Pool *self) 17 | { 18 | LIST_FOREACH(self->refs, i, ref, self->freeFunc(ref);); 19 | List_free(self->refs); 20 | 21 | LIST_FOREACH(self->recycled, i, ref, self->freeFunc(ref);); 22 | List_free(self->recycled); 23 | 24 | free(self); 25 | } 26 | 27 | 28 | void Pool_freeRecycled(Pool *self) 29 | { 30 | LIST_FOREACH(self->recycled, i, ref, self->freeFunc(ref);); 31 | List_removeAll(self->recycled); 32 | } 33 | 34 | void Pool_freeRefs(Pool *self) 35 | { 36 | PoolFreeFunc *freeFunc = self->freeFunc; 37 | 38 | LIST_FOREACH(self->refs, i, ref, 39 | if(List_size(self->recycled) < self->recycleSize) 40 | { 41 | self->clearFunc(ref); 42 | List_append_(self->recycled, ref); 43 | } 44 | else 45 | { 46 | freeFunc(ref); 47 | } 48 | ); 49 | 50 | List_removeAll(self->refs); 51 | } 52 | 53 | void Pool_setNewFunc_(Pool *self, PoolNewFunc *f) 54 | { 55 | self->newFunc = f; 56 | } 57 | 58 | void Pool_setFreeFunc_(Pool *self, PoolFreeFunc *f) 59 | { 60 | self->freeFunc = f; 61 | } 62 | 63 | void Pool_setClearFunc_(Pool *self, PoolClearFunc *f) 64 | { 65 | self->clearFunc = f; 66 | } 67 | 68 | void Pool_setRecycleSize_(Pool *self, int size) 69 | { 70 | self->recycleSize = size; 71 | } 72 | 73 | void *Pool_newItem(Pool *self) 74 | { 75 | void *ref; 76 | 77 | if(List_size(self->recycled)) 78 | { 79 | ref = List_pop(self->recycled); 80 | } 81 | else 82 | { 83 | ref = self->newFunc(); 84 | } 85 | 86 | List_append_(self->refs, ref); 87 | return ref; 88 | } 89 | 90 | void Pool_showStats(Pool *self) 91 | { 92 | printf("pool total: %i refs: %i recycled: %i recycleSize: %i\n", 93 | (int)List_size(self->refs) + (int)List_size(self->recycled), 94 | (int)List_size(self->refs), 95 | (int)List_size(self->recycled), 96 | (int)self->recycleSize); 97 | } 98 | 99 | -------------------------------------------------------------------------------- /source/pdb/Pool.h: -------------------------------------------------------------------------------- 1 | #ifndef Pool_DEFINED 2 | #define Pool_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include "List.h" 10 | 11 | typedef void *(PoolNewFunc)(void); 12 | typedef void (PoolFreeFunc)(void *); 13 | typedef void (PoolClearFunc)(void *); 14 | 15 | typedef struct 16 | { 17 | List *refs; 18 | PoolNewFunc *newFunc; 19 | PoolFreeFunc *freeFunc; 20 | PoolClearFunc *clearFunc; 21 | List *recycled; 22 | int recycleSize; 23 | } Pool; 24 | 25 | Pool *Pool_new(void); 26 | void Pool_free(Pool *self); 27 | void Pool_freeRefs(Pool *self); 28 | void Pool_freeRecycled(Pool *self); 29 | void Pool_setNewFunc_(Pool *self, PoolNewFunc *func); 30 | void Pool_setFreeFunc_(Pool *self, PoolFreeFunc *func); 31 | void Pool_setClearFunc_(Pool *self, PoolClearFunc *func); 32 | void Pool_setRecycleSize_(Pool *self, int size); 33 | void *Pool_newItem(Pool *self); 34 | void Pool_showStats(Pool *self); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | #endif 40 | -------------------------------------------------------------------------------- /source/pdb/Yajl_extras.c: -------------------------------------------------------------------------------- 1 | #include "Yajl_extras.h" 2 | #include 3 | #include 4 | 5 | void yajl_gen_cstring(yajl_gen self, const char *s) 6 | { 7 | yajl_gen_string(self, (const unsigned char *)s, strlen(s)); 8 | } 9 | 10 | void yajl_gen_datum(yajl_gen self, Datum *d) 11 | { 12 | yajl_gen_string(self, (const unsigned char *)Datum_data(d), Datum_size(d)); 13 | } 14 | 15 | void Datum_appendYajl_(Datum *self, yajl_gen y) 16 | { 17 | const unsigned char *jsonBuffer; 18 | size_t jsonBufferLength; 19 | 20 | yajl_gen_get_buf(y, &jsonBuffer, &jsonBufferLength); 21 | 22 | Datum_appendBytes_size_(self, jsonBuffer, (size_t)jsonBufferLength); 23 | yajl_gen_clear(y); 24 | } 25 | 26 | void Datum_setYajl_(Datum *self, yajl_gen y) 27 | { 28 | const unsigned char *jsonBuffer; 29 | size_t jsonBufferLength; 30 | 31 | yajl_gen_get_buf(y, &jsonBuffer, &jsonBufferLength); 32 | 33 | Datum_setData_size_(self, (char *)jsonBuffer, (size_t)jsonBufferLength); 34 | yajl_gen_clear(y); 35 | } 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /source/pdb/Yajl_extras.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef YAJL_EXTRAS_DEFINED 3 | #define YAJL_EXTRAS_DEFINED 1 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "Datum.h" 10 | #include 11 | 12 | void yajl_gen_cstring(yajl_gen self, const char *s); 13 | void yajl_gen_datum(yajl_gen self, Datum *d); 14 | 15 | void Datum_appendYajl_(Datum *self, yajl_gen y); 16 | void Datum_setYajl_(Datum *self, yajl_gen y); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | #endif 22 | -------------------------------------------------------------------------------- /source/store/Store.c: -------------------------------------------------------------------------------- 1 | /* 2 | Notes: 3 | tcbdboptimize() only works on hash dbs, so we can't use it - use collectgarbage instead 4 | */ 5 | 6 | #include "Store.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | Store *Store_new(void) 15 | { 16 | Store *self = calloc(1, sizeof(Store)); 17 | Store_setPath_(self, "default.store"); 18 | return self; 19 | } 20 | 21 | void Store_free(Store *self) 22 | { 23 | Store_close(self); 24 | free(self->path); 25 | free(self); 26 | } 27 | 28 | void Store_setPath_(Store *self, const char *p) 29 | { 30 | self->path = strcpy(realloc(self->path, strlen(p)+1), p); 31 | } 32 | 33 | const char *Store_path(Store *self) 34 | { 35 | return self->path; 36 | } 37 | 38 | void Store_setCompareFunction_(Store *self, void *func) 39 | { 40 | self->compareFunc = func; 41 | } 42 | 43 | void Store_setHardSync_(Store *self, int aBool) 44 | { 45 | self->hardSync = aBool; 46 | } 47 | 48 | 49 | int Store_open(Store *self) 50 | { 51 | self->db = tcbdbnew(); 52 | 53 | /* 54 | //Tinkering with these seems to result in worse performance so far... 55 | 56 | tcbdbsetxmsiz(self->db, 1024*1024*64); 57 | 58 | if(!tcbdbtune(self->db, 0, 0, 0, -1, -1, BDBTDEFLATE)) // HDBTLARGE 59 | { 60 | Log_Printf("tcbdbtune failed\n"); 61 | return -1; 62 | } 63 | */ 64 | 65 | /* 66 | if (!tcbdbsetcache(self->db, 0, 512*4096)) 67 | { 68 | //Log_Printf("tcbdbsetcache failed\n"); 69 | return -1; 70 | } 71 | */ 72 | 73 | if (!tcbdbsetcmpfunc(self->db, self->compareFunc, NULL)) 74 | { 75 | return 0; 76 | } 77 | 78 | { 79 | int flags = BDBOWRITER | BDBOCREAT | BDBONOLCK; 80 | 81 | if (self->hardSync) 82 | { 83 | printf("Store: hard disk syncing enabled\n"); 84 | flags |= BDBOTSYNC; 85 | } 86 | 87 | if (!tcbdbopen(self->db, self->path, flags)) 88 | { 89 | return 0; 90 | } 91 | } 92 | 93 | return 1; 94 | } 95 | 96 | int Store_isOpen(Store *self) 97 | { 98 | return self->db != 0x0; 99 | } 100 | 101 | int Store_close(Store *self) 102 | { 103 | int r = 0; 104 | 105 | if (self->db) 106 | { 107 | tcbdbclose(self->db); 108 | tcbdbdel(self->db); 109 | self->db = 0x0; 110 | self->inTransaction = 0; 111 | } 112 | 113 | return r; 114 | } 115 | 116 | int Store_backup(Store *self, const char *backupPath) 117 | { 118 | return tcbdbcopy(self->db, backupPath); //tc will create a .wal file 119 | } 120 | 121 | const char *Store_error(Store *self) 122 | { 123 | return tcbdberrmsg(tcbdbecode(self->db)); 124 | } 125 | 126 | char *Store_read(Store *self, const char *k, size_t ksize, int *vsize) 127 | { 128 | void *v = tcbdbget(self->db, k, ksize, vsize); 129 | return v; 130 | } 131 | 132 | int Store_write(Store *self, const char *k, size_t ksize, const char *v, size_t vsize) 133 | { 134 | if(!tcbdbput(self->db, k, ksize, v, vsize)) 135 | { 136 | return 0; 137 | } 138 | 139 | return 1; 140 | } 141 | 142 | int Store_append(Store *self, const char *k, size_t ksize, const char *v, size_t vsize) 143 | { 144 | if(!tcbdbputcat(self->db, k, ksize, v, vsize)) 145 | { 146 | return 0; 147 | } 148 | 149 | return 1; 150 | } 151 | 152 | int Store_remove(Store *self, const char *k, size_t ksize) 153 | { 154 | if(!tcbdbout(self->db, k, ksize)) 155 | { 156 | return 0; 157 | } 158 | 159 | return 1; 160 | } 161 | 162 | int Store_sync(Store *self) 163 | { 164 | if(!tcbdbsync(self->db)) 165 | { 166 | return 0; 167 | } 168 | 169 | return 1; 170 | } 171 | 172 | int Store_inTransaction(Store *self) 173 | { 174 | return self->inTransaction; 175 | } 176 | 177 | int Store_begin(Store *self) 178 | { 179 | if(self->inTransaction) 180 | { 181 | return 0; 182 | } 183 | 184 | if (!tcbdbtranbegin(self->db)) 185 | { 186 | return 0; 187 | } 188 | 189 | self->inTransaction = 1; 190 | 191 | return 1; 192 | } 193 | 194 | int Store_abort(Store *self) 195 | { 196 | if (!tcbdbtranabort(self->db)) 197 | { 198 | return 0; 199 | } 200 | 201 | self->inTransaction = 0; 202 | 203 | return 1; 204 | } 205 | 206 | int Store_commit(Store *self) 207 | { 208 | if (!tcbdbtrancommit(self->db)) 209 | { 210 | return 0; 211 | } 212 | 213 | self->inTransaction = 0; 214 | 215 | return 1; 216 | } 217 | 218 | uint64_t Store_size(Store *self) 219 | { 220 | return tcbdbfsiz(self->db); 221 | } 222 | 223 | uint64_t Store_numberOfKeys(Store *self) 224 | { 225 | return tcbdbrnum(self->db); 226 | } 227 | 228 | -------------------------------------------------------------------------------- /source/store/Store.h: -------------------------------------------------------------------------------- 1 | #ifndef Store_DEFINED 2 | #define Store_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include "StoreCursor.h" 11 | 12 | //typedef void (StoreRequestCallback)(void *); 13 | //typedef void (StoreWriteMethod)(void *); 14 | 15 | typedef struct 16 | { 17 | /* 18 | StoreWriteMethod *write; 19 | StoreWriteMethod *readQuery; 20 | StoreWriteMethod *readPost; 21 | StoreWriteMethod *readPost; 22 | */ 23 | char *path; 24 | void *compareFunc; 25 | void *db; 26 | int hardSync; 27 | int inTransaction; 28 | } Store; 29 | 30 | Store *Store_new(void); 31 | void Store_free(Store *self); 32 | 33 | void Store_setCompareFunction_(Store *self, void *func); 34 | void Store_setHardSync_(Store *self, int aBool); 35 | 36 | void Store_setPath_(Store *self, const char *p); 37 | const char *Store_path(Store *self); 38 | 39 | int Store_open(Store *self); 40 | int Store_isOpen(Store *self); 41 | int Store_close(Store *self); 42 | int Store_backup(Store *self, const char *backupPath); 43 | 44 | const char *Store_error(Store *self); 45 | 46 | char *Store_read(Store *self, const char *k, size_t ksize, int *vsize); 47 | int Store_write(Store *self, const char *k, size_t ksize, const char *v, size_t vsize); 48 | int Store_append(Store *self, const char *k, size_t ksize, const char *v, size_t vsize); 49 | int Store_remove(Store *self, const char *k, size_t ksize); 50 | int Store_sync(Store *self); 51 | 52 | int Store_begin(Store *self); 53 | int Store_abort(Store *self); 54 | int Store_commit(Store *self); 55 | 56 | uint64_t Store_size(Store *self); 57 | uint64_t Store_numberOfKeys(Store *self); 58 | 59 | //StoreCursor *Store_newCursor(Store *self); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | #endif 65 | -------------------------------------------------------------------------------- /source/store/StoreCursor.c: -------------------------------------------------------------------------------- 1 | #include "StoreCursor.h" 2 | #include "Store.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | StoreCursor *StoreCursor_new(void) 11 | { 12 | StoreCursor *self = calloc(1, sizeof(StoreCursor)); 13 | 14 | return self; 15 | } 16 | 17 | void StoreCursor_free(StoreCursor *self) 18 | { 19 | StoreCursor_close(self); 20 | free(self); 21 | } 22 | 23 | void StoreCursor_setStore_(StoreCursor *self, void *store) 24 | { 25 | self->store = store; 26 | } 27 | 28 | 29 | void StoreCursor_open(StoreCursor *self) 30 | { 31 | self->cursor = tcbdbcurnew(((Store *)self->store)->db); 32 | } 33 | 34 | void StoreCursor_close(StoreCursor *self) 35 | { 36 | if(self->cursor) 37 | { 38 | tcbdbcurdel(self->cursor); 39 | self->cursor = 0x0; 40 | } 41 | } 42 | 43 | int StoreCursor_next(StoreCursor *self) 44 | { 45 | return tcbdbcurnext(self->cursor); 46 | } 47 | 48 | int StoreCursor_previous(StoreCursor *self) 49 | { 50 | return tcbdbcurprev(self->cursor); 51 | } 52 | 53 | void StoreCursor_jump(StoreCursor *self, const char *k, size_t ksize) 54 | { 55 | tcbdbcurjump(self->cursor, k, ksize); 56 | } 57 | 58 | int StoreCursor_remove(StoreCursor *self) 59 | { 60 | return tcbdbcurout(self->cursor); 61 | } 62 | 63 | char *StoreCursor_key(StoreCursor *self, int *size) 64 | { 65 | return tcbdbcurkey(self->cursor, size); 66 | } 67 | 68 | char *StoreCursor_value(StoreCursor *self, int *size) 69 | { 70 | return tcbdbcurval(self->cursor, size); 71 | } 72 | 73 | 74 | //void StoreCursor_first(StoreCursor *self); 75 | //void StoreCursor_last(StoreCursor *self) -------------------------------------------------------------------------------- /source/store/StoreCursor.h: -------------------------------------------------------------------------------- 1 | #ifndef StoreCursor_DEFINED 2 | #define StoreCursor_DEFINED 1 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include "Date.h" 11 | 12 | typedef struct 13 | { 14 | void *store; 15 | void *cursor; 16 | } StoreCursor; 17 | 18 | StoreCursor *StoreCursor_new(void); 19 | void StoreCursor_free(StoreCursor *self); 20 | 21 | void StoreCursor_setStore_(StoreCursor *self, void *store); 22 | 23 | void StoreCursor_open(StoreCursor *self); 24 | void StoreCursor_close(StoreCursor *self); 25 | 26 | int StoreCursor_next(StoreCursor *self); 27 | int StoreCursor_previous(StoreCursor *self); 28 | void StoreCursor_jump(StoreCursor *self, const char *k, size_t ksize); 29 | int StoreCursor_remove(StoreCursor *self); 30 | 31 | char *StoreCursor_key(StoreCursor *self, int *size); 32 | char *StoreCursor_value(StoreCursor *self, int *size); 33 | 34 | //void StoreCursor_first(StoreCursor *self); 35 | //void StoreCursor_last(StoreCursor *self); 36 | //void StoreCursor_insert(StoreCursor *self); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | #endif 42 | -------------------------------------------------------------------------------- /tests/db/.gitisdumb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevedekorte/vertexdb/8fbb2fa0a750bb100a8d6563fefa7721ee2b6b02/tests/db/.gitisdumb -------------------------------------------------------------------------------- /tests/pnode.io: -------------------------------------------------------------------------------- 1 | File with("urls.txt") contents split("\n") foreach(u, URL with("http://localhost:8080" .. u) fetch println) 2 | -------------------------------------------------------------------------------- /tests/stress.io: -------------------------------------------------------------------------------- 1 | // Io is the bottle neck for this test - this is more of a performance sanity check 2 | 3 | for(v, 1, 10000, 4 | URL with("http://localhost:8080?action=write&value=" .. v) fetch 5 | if(v % 1000 == 0, writeln(v)) 6 | ) 7 | 8 | URL with("http://localhost:8080?action=collectGarbage") fetch 9 | -------------------------------------------------------------------------------- /tests/test.py: -------------------------------------------------------------------------------- 1 | import urllib2 2 | from urllib2 import urlopen 3 | 4 | class VertexDb: 5 | 6 | def __init__(self, host="http//localhost:8080"): 7 | self.host = host 8 | 9 | def __str__(self): 10 | return "vertexdb at %s" % self.host 11 | 12 | def write(self, path, key, val): 13 | return urlopen("%s%s%s%s" % (self.host, path, "/?action=write&key=", key), val).read() 14 | 15 | def read(self, path, key): 16 | return urlopen("%s%s%s%s" % (self.host, path, "/?action=read&key=", key)).read() 17 | 18 | def mkdir(self, path): 19 | return urlopen("%s%s%s" % (self.host, path, "/?action=mkdir")).read() 20 | 21 | def size(self, path): 22 | """docstring for size""" 23 | return urlopen("%s%s%s" % (self.host, path, "/?action=size")).read() 24 | 25 | vdb = VertexDb("http://localhost:8080") 26 | print vdb.size("/") 27 | vdb.mkdir("/test/") 28 | vdb.write("/test/", "akey", "avalue") 29 | print vdb.read("/test/", "akey") 30 | 31 | # Implement protocols so that nodes can be used as dictionaries etc? 32 | # Look at fs APIs. -------------------------------------------------------------------------------- /tests/write_test.io: -------------------------------------------------------------------------------- 1 | // tests for the write action 2 | 3 | assertEquals := method(a, b, 4 | if(a != b, 5 | Exception raise(call message argAt(0) .. " == " .. a .. " instead of " .. b) 6 | ) 7 | ) 8 | 9 | base := "http://localhost:8080" 10 | 11 | // two ways to write 12 | 13 | URL with(base .. "/?action=write&key=_testkey1&value=testval1") fetch 14 | URL with(base .. "/?action=write&key=_testkey2") post("testval2") 15 | assertEquals(URL with(base .. "/?action=read&key=_testkey1") fetch, "\"testval1\"") 16 | assertEquals(URL with(base .. "/?action=read&key=_testkey2") fetch, "\"testval2\"") 17 | 18 | // can create empty keys 19 | 20 | URL with(base .. "/?action=write&key=_testkey3&value=") fetch 21 | URL with(base .. "/?action=write&key=_testkey4") post("") 22 | assertEquals(URL with(base .. "/?action=read&key=_testkey3") fetch, "\"\"") 23 | assertEquals(URL with(base .. "/?action=read&key=_testkey4") fetch, "\"\"") -------------------------------------------------------------------------------- /vertexdb.tmproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | documents 6 | 7 | 8 | expanded 9 | 10 | name 11 | vertexdb 12 | regexFolderFilter 13 | !.*/(\.[^/]*|CVS|_darcs|_MTN|\{arch\}|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$ 14 | sourceDirectory 15 | 16 | 17 | 18 | fileHierarchyDrawerWidth 19 | 249 20 | metaData 21 | 22 | source/pdb/Log.h 23 | 24 | caret 25 | 26 | column 27 | 19 28 | line 29 | 24 30 | 31 | columnSelection 32 | 33 | firstVisibleColumn 34 | 0 35 | firstVisibleLine 36 | 0 37 | selectFrom 38 | 39 | column 40 | 8 41 | line 42 | 24 43 | 44 | selectTo 45 | 46 | column 47 | 19 48 | line 49 | 24 50 | 51 | 52 | 53 | showFileHierarchyDrawer 54 | 55 | windowFrame 56 | {{56, 0}, {1606, 1058}} 57 | 58 | 59 | -------------------------------------------------------------------------------- /vertexdb_admin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "rubygems" 4 | require "net/http" 5 | 6 | $port = ARGV.shift 7 | 8 | DOMAIN = '127.0.0.1' 9 | 10 | def show_help 11 | puts <<-TT 12 | VertexDB maintaning tool 13 | ------------------------ 14 | Usage: vertexdb_admin [] 15 | Avaliable commands: 16 | backup 17 | clear 18 | collect_garbage 19 | TT 20 | end 21 | 22 | def send_request uri 23 | res = "" 24 | puts "-- SENDING #{uri}" 25 | $connection.get(uri) {|r| res += r } 26 | puts ">>> " + res 27 | end 28 | 29 | if ARGV.index('--help') || ARGV.index('-h') || ARGV.size == 0 30 | show_help 31 | exit 32 | end 33 | 34 | $connection = Net::HTTP.start(DOMAIN, $port) 35 | puts "== connected to #{DOMAIN}:#{$port}" 36 | 37 | case ARGV.shift 38 | when 'backup' 39 | send_request '/?action=backup' 40 | puts "== backup made" 41 | 42 | when 'clear' 43 | send_request '/?action=select&op=rm' 44 | puts "== root nodes removed" 45 | 46 | when 'collect_garbage' 47 | send_request '/?action=collectGarbage' 48 | puts "== garbage collected" 49 | else 50 | puts "Undefined command" 51 | puts "See vertexdb_admin --help" 52 | end --------------------------------------------------------------------------------