diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..e69de29b diff --git a/include/dll.h b/include/dll.h index c946e4a3..03357c79 100644 --- a/include/dll.h +++ b/include/dll.h @@ -532,4 +532,8 @@ EXTERN_C DLLEXPORT void STDCALL ErrorMessage( int code, char line[80]); +EXTERN_C DLLEXPORT char * STDCALL JsonApi_CalcAllTables(const char * params); + +EXTERN_C DLLEXPORT void STDCALL JsonApi_FreeCPtr(void * ptr); + #endif diff --git a/src/Init.cpp b/src/Init.cpp index 5c2fff0c..3aad3dbe 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -343,8 +343,9 @@ void InitConstants() groupData[ris].rank[g] = topBitNo; groupData[ris].sequence[g] = 0; groupData[ris].fullseq[g] = topBitRank; - groupData[ris].gap[g] = - topside[topBitNo] & botside[ groupData[ris].rank[g - 1] ]; + groupData[ris].gap[g] = (g == 0 ? + topside[topBitNo] & botside[ 0 ] : + topside[topBitNo] & botside[ groupData[ris].rank[g - 1] ]); } } } diff --git a/src/JsonApi.cpp b/src/JsonApi.cpp new file mode 100644 index 00000000..3d3073ab --- /dev/null +++ b/src/JsonApi.cpp @@ -0,0 +1,126 @@ +#include +#include + +#include "CalcTables.h" +#include "dds.h" + +using namespace std; +using namespace rapidjson; +// using json = nlohmann::json; + +static char * TableResultToJson(const ddTableResults * table); +static char * ErrorToJson(const char * error); + +char * STDCALL JsonApi_CalcAllTables(const char * params) +{ + Document jobj; + jobj.Parse(params); + + ddTableDealsPBN pbnDeals; + pbnDeals.noOfTables = 1; + strcpy(pbnDeals.deals[0].cards, jobj["pbn"].GetString()); + + ddTablesRes table; + allParResults pres; + + int mode = 0; // No par calculation + int trumpFilter[DDS_STRAINS] = {0, 0, 0, 0, 0}; // All + int res = CalcAllTablesPBN(&pbnDeals, 0, trumpFilter, &table, &pres); + + if (res != RETURN_NO_FAULT) + { + char line[80]; + ErrorMessage(res, line); + return ErrorToJson(line); + } + + return TableResultToJson(&table.results[0]); +} + +void STDCALL JsonApi_FreeCPtr(void * ptr) +{ + free(ptr); +} + +static char * ErrorToJson(const char * error) +{ + StringBuffer sb; + Writer writer(sb); + + writer.StartObject(); + + writer.Key("error"); + writer.String(error); + + writer.EndObject(); + + return strdup(sb.GetString()); +} + +static char * TableResultToJson(const ddTableResults * table) +{ + StringBuffer sb; + Writer writer(sb); + + writer.StartObject(); + + writer.Key("north"); + writer.StartObject(); + writer.Key("s"); + writer.Int(table->resTable[0][0]); + writer.Key("h"); + writer.Int(table->resTable[1][0]); + writer.Key("d"); + writer.Int(table->resTable[2][0]); + writer.Key("c"); + writer.Int(table->resTable[3][0]); + writer.Key("n"); + writer.Int(table->resTable[4][0]); + writer.EndObject(); + + writer.Key("east"); + writer.StartObject(); + writer.Key("s"); + writer.Int(table->resTable[0][1]); + writer.Key("h"); + writer.Int(table->resTable[1][1]); + writer.Key("d"); + writer.Int(table->resTable[2][1]); + writer.Key("c"); + writer.Int(table->resTable[3][1]); + writer.Key("n"); + writer.Int(table->resTable[4][1]); + writer.EndObject(); + + writer.Key("south"); + writer.StartObject(); + writer.Key("s"); + writer.Int(table->resTable[0][2]); + writer.Key("h"); + writer.Int(table->resTable[1][2]); + writer.Key("d"); + writer.Int(table->resTable[2][2]); + writer.Key("c"); + writer.Int(table->resTable[3][2]); + writer.Key("n"); + writer.Int(table->resTable[4][2]); + writer.EndObject(); + + writer.Key("west"); + writer.StartObject(); + writer.Key("s"); + writer.Int(table->resTable[0][3]); + writer.Key("h"); + writer.Int(table->resTable[1][3]); + writer.Key("d"); + writer.Int(table->resTable[2][3]); + writer.Key("c"); + writer.Int(table->resTable[3][3]); + writer.Key("n"); + writer.Int(table->resTable[4][3]); + writer.EndObject(); + + writer.EndObject(); + + return strdup(sb.GetString()); +} \ No newline at end of file diff --git a/src/Makefiles/Makefile_linux_shared b/src/Makefiles/Makefile_linux_shared index ec4a2c8a..5b4d80f6 100644 --- a/src/Makefiles/Makefile_linux_shared +++ b/src/Makefiles/Makefile_linux_shared @@ -81,9 +81,18 @@ WARN_FLAGS = \ -Wno-long-long \ -Wno-format +# SANITIZE_FLAGS = \ +# -fsanitize=address \ +# -fsanitize=bounds \ +# -fsanitize=object-size \ +# -fno-omit-frame-pointer + +SANITIZE_FLAGS = + COMPILE_FLAGS = -fPIC -O3 -flto -fopenmp -mtune=generic -std=c++11 \ $(WARN_FLAGS) \ - $(DDS_BEHAVIOR) $(THREAD_COMPILE) $(THREADING) + $(DDS_BEHAVIOR) $(THREAD_COMPILE) $(THREADING) \ + $(SANITIZE_FLAGS) DLLBASE = dds SHARED_LIB = lib$(DLLBASE).so @@ -100,8 +109,8 @@ LINK_FLAGS = \ -Wl,-z \ -Wl,relro \ $(THREAD_LINK) \ - -fPIC - + -fPIC \ + $(SANITIZE_FLAGS) linux: $(O_FILES) $(CC) \ diff --git a/src/Makefiles/depends_o.txt b/src/Makefiles/depends_o.txt index f705666f..cbff05b1 100644 --- a/src/Makefiles/depends_o.txt +++ b/src/Makefiles/depends_o.txt @@ -16,6 +16,7 @@ File.o: File.h Init.o: Init.h dds.h ../include/portab.h ../include/dll.h Memory.h Init.o: TransTable.h TransTableS.h TransTableL.h Moves.h File.h debug.h Init.o: System.h Scheduler.h TimeStatList.h TimeStat.h Timer.h +JsonApi.o: CalcTables.h dds.h ../include/portab.h ../include/dll.h LaterTricks.o: LaterTricks.h dds.h ../include/portab.h ../include/dll.h LaterTricks.o: Memory.h TransTable.h TransTableS.h TransTableL.h Moves.h LaterTricks.o: File.h debug.h diff --git a/src/Makefiles/sources.txt b/src/Makefiles/sources.txt index 566a0584..dcfd0506 100644 --- a/src/Makefiles/sources.txt +++ b/src/Makefiles/sources.txt @@ -7,6 +7,7 @@ SOURCE_FILES = \ DealerPar.cpp \ File.cpp \ Init.cpp \ + JsonApi.cpp \ LaterTricks.cpp \ Memory.cpp \ Moves.cpp \ diff --git a/src/Memory.cpp b/src/Memory.cpp index f333d01f..73476477 100644 --- a/src/Memory.cpp +++ b/src/Memory.cpp @@ -8,6 +8,7 @@ */ +#include "Init.h" #include "Memory.h" @@ -19,6 +20,8 @@ Memory::Memory() Memory::~Memory() { + CloseDebugFiles(); + FreeMemory(); } @@ -30,6 +33,7 @@ void Memory::Reset() void Memory::ResetThread(const unsigned thrId) { + if(memory[thrId] == nullptr || memory[thrId]->transTable == nullptr) return; memory[thrId]->transTable->ResetMemory(TT_RESET_FREE_MEMORY); memory[thrId]->memUsed = Memory::MemoryInUseMB(thrId); } @@ -37,8 +41,11 @@ void Memory::ResetThread(const unsigned thrId) void Memory::ReturnThread(const unsigned thrId) { + if(memory[thrId] == nullptr || memory[thrId]->transTable == nullptr) return; memory[thrId]->transTable->ReturnAllMemory(); memory[thrId]->memUsed = Memory::MemoryInUseMB(thrId); + delete memory[thrId]->transTable; + delete memory[thrId]; } @@ -103,7 +110,7 @@ ThreadData * Memory::GetPtr(const unsigned thrId) { if (thrId >= nThreads) { - cout << "Memory::GetPtr: " << thrId << " vs. " << nThreads << endl; + cout << "Memory::GetPtr: " << thrId << " vs. " << nThreads << " vs. " << memory.size() << endl; exit(1); } return memory[thrId]; @@ -112,6 +119,7 @@ ThreadData * Memory::GetPtr(const unsigned thrId) double Memory::MemoryInUseMB(const unsigned thrId) const { + if(memory[thrId] == nullptr || memory[thrId]->transTable == nullptr) return -101; return memory[thrId]->transTable->MemoryInUse() + 8192. * sizeof(relRanksType) / static_cast(1024.); } diff --git a/src/dds.cpp b/src/dds.cpp index fad30225..0048df95 100644 --- a/src/dds.cpp +++ b/src/dds.cpp @@ -72,8 +72,6 @@ static void __attribute__ ((constructor)) libInit(void) static void __attribute__ ((destructor)) libEnd(void) { - CloseDebugFiles(); - FreeMemory(); } #endif