Mercurial > hg > orthanc-stone
changeset 495:6405435480ae bgo-commands-codegen
Fixed template to add dump capabilities + started work on an integrated TS/WASM test
line wrap: on
line diff
--- a/.hgignore Sat Feb 23 10:18:13 2019 +0100 +++ b/.hgignore Sat Feb 23 14:14:32 2019 +0100 @@ -15,3 +15,5 @@ Resources/CodeGeneration/build_browser/ Resources/CodeGeneration/testCppHandler/build/ Resources/CodeGeneration/testCppHandler/build_msbuild/ +syntax: glob +Resources/CodeGeneration/testWasmIntegrated/build-wasm/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/playground.ts Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,259 @@ +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ + +namespace VsolStuff +{ + enum EnumMonth0 + { + January, + February, + March + }; + + // interface Serializer + // { + // Serialize(value: number): string; + // Serialize(value: string): string; + // Serialize(value: EnumMonth0): string; + // }; + function printf(value: any):void + { + console.log(value) + } + + // function StoneSerialize(value: string) : string; + // function StoneSerialize(value: number) : string; + // function StoneSerialize(value: EnumMonth0) : string; + function StoneSerialize<T>(value: T[]) : string; + + function StoneSerialize<T>(value: T[] | EnumMonth0) : string + { + let valueType = typeof value; + printf(`About to serialize value. Type is ${valueType}`) + printf(`About to serialize value. Type is ${typeof value}`) + return "Choucroute"; + } + + function main():number + { + enum Color {Red = 1, Green = 2, Blue = 4} + let color: Color = Color.Green; + printf("---------------------------"); + printf(`typeof color: ${typeof color}`); + printf("---------------------------"); + let colors: Color[] = [] + colors.push(Color.Green); + colors.push(Color.Red); + printf(`typeof colors: ${typeof colors}`); + printf(`Array.isArray(colors): ${Array.isArray(colors)}`); + printf("---------------------------"); + + + let toto:EnumMonth0[] = []; + + toto.push(EnumMonth0.February); + toto.push(EnumMonth0.March); + + printf(JSON.stringify(toto)); + + return 0; + + } + + main() + +// string StoneSerialize_number(int32_t value) +// { + +// Json::Value result(value); +// return result; +// } + +// Json::Value StoneSerialize(double value) +// { +// Json::Value result(value); +// return result; +// } + +// Json::Value StoneSerialize(bool value) +// { +// Json::Value result(value); +// return result; +// } + +// Json::Value StoneSerialize(const std::string& value) +// { +// // the following is better than +// Json::Value result(value.data(),value.data()+value.size()); +// return result; +// } + +// template<typename T> +// Json::Value StoneSerialize(const std::map<std::string,T>& value) +// { +// Json::Value result(Json::objectValue); + +// for (std::map<std::string, T>::const_iterator it = value.cbegin(); +// it != value.cend(); ++it) +// { +// // it->first it->second +// result[it->first] = StoneSerialize(it->second); +// } +// return result; +// } + +// template<typename T> +// Json::Value StoneSerialize(const std::vector<T>& value) +// { +// Json::Value result(Json::arrayValue); +// for (size_t i = 0; i < value.size(); ++i) +// { +// result.append(StoneSerialize(value[i])); +// } +// return result; +// } + +// enum EnumMonth0 +// { +// January, +// February, +// March +// }; + +// std::string ToString(EnumMonth0 value) +// { +// switch(value) +// { +// case January: +// return "January"; +// case February: +// return "February"; +// case March: +// return "March"; +// default: +// { +// std::stringstream ss; +// ss << "Unrecognized EnumMonth0 value (" << static_cast<int64_t>(value) << ")"; +// throw std::runtime_error(ss.str()); +// } +// } +// } + +// void FromString(EnumMonth0& value, std::string strValue) +// { +// if (strValue == "January" || strValue == "EnumMonth0_January") +// { +// return January; +// } +// else if (strValue == "February" || strValue == "EnumMonth0_February") +// { +// return February; +// } +// #error Not implemented yet +// } + +// Json::Value StoneSerialize(const EnumMonth0& value) +// { +// return StoneSerialize(ToString(value)); +// } +// struct Message1 +// { +// int32_t a; +// std::string b; +// EnumMonth0 c; +// bool d; +// }; + +// struct Message2 +// { +// std::string toto; +// std::vector<Message1> tata; +// std::vector<std::string> tutu; +// std::map<std::string, std::string> titi; +// std::map<std::string, Message1> lulu; +// }; + +// Json::Value StoneSerialize(const Message1& value) +// { +// Json::Value result(Json::objectValue); +// result["a"] = StoneSerialize(value.a); +// result["b"] = StoneSerialize(value.b); +// result["c"] = StoneSerialize(value.c); +// result["d"] = StoneSerialize(value.d); +// return result; +// } + +// Json::Value StoneSerialize(const Message2& value) +// { +// Json::Value result(Json::objectValue); +// result["toto"] = StoneSerialize(value.toto); +// result["tata"] = StoneSerialize(value.tata); +// result["tutu"] = StoneSerialize(value.tutu); +// result["titi"] = StoneSerialize(value.titi); +// result["lulu"] = StoneSerialize(value.lulu); +// return result; +// } +// } + +// int main() +// { +// VsolStuff::Message1 msg1_0; +// msg1_0.a = 42; +// msg1_0.b = "Benjamin"; +// msg1_0.c = VsolStuff::January; +// msg1_0.d = true; + +// VsolStuff::Message1 msg1_1; +// msg1_1.a = 43; +// msg1_1.b = "Sandrine"; +// msg1_1.c = VsolStuff::March; +// msg1_0.d = false; + +// // std::string toto; +// // std::vector<Message1> tata; +// // std::vector<std::string> tutu; +// // std::map<int32_t, std::string> titi; +// // std::map<int32_t, Message1> lulu; + +// VsolStuff::Message2 msg2_0; +// msg2_0.toto = "Prout zizi"; +// msg2_0.tata.push_back(msg1_0); +// msg2_0.tata.push_back(msg1_1); +// msg2_0.tutu.push_back("Mercadet"); +// msg2_0.tutu.push_back("Poisson"); +// msg2_0.titi["44"] = "key 44"; +// msg2_0.titi["45"] = "key 45"; +// msg2_0.lulu["54"] = msg1_1; +// msg2_0.lulu["55"] = msg1_0; +// auto result = VsolStuff::StoneSerialize(msg2_0); +// auto resultStr = result.toStyledString(); + +// Json::Value readValue; + +// Json::CharReaderBuilder builder; +// Json::CharReader* reader = builder.newCharReader(); +// std::string errors; + +// bool ok = reader->parse( +// resultStr.c_str(), +// resultStr.c_str() + resultStr.size(), +// &readValue, +// &errors +// ); +// delete reader; + +// if (!ok) +// { +// std::stringstream ss; +// ss << "Json parsing error: " << errors; +// throw std::runtime_error(ss.str()); +// } +// std::cout << readValue.get("toto", "Default Value").asString() << std::endl; +// return 0; +// } + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/playground2.ts Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,72 @@ +class Greeter { + greeting: string; + constructor(message: string) { + this.greeting = message; + } + greet() { + return "Hello, " + this.greeting; + } +} +enum Color { + Red, + Green, + Blue, +}; + +function ColorToString(value: Color) +{ + switch (value) + { + case Color.Red: + return "Red"; + case Color.Green: + return "Green"; + case Color.Blue: + return "Blue"; + default: + throw new Error(`Unrecognized Color value(${value})`); + } +} + +let color: Color = Color.Red; + +document.body.textContent = "<p>---------------------</p>" +document.body.textContent += "<p>********************************</p>" + +class TestMessage { + s1: string; + s2: Array<string>; + s3: Array<Array<string>>; + s4: Map<string, number>; + s5: Map<number, Array<string>>; + s6: Color; + s7: boolean; +} + +let tm = new TestMessage(); +tm.s2 = new Array<string>() +tm.s2.push("toto"); +tm.s2.push("toto2"); +tm.s2.push("toto3"); +tm.s4 = new Map<string, number>(); +tm.s4["toto"] = 42; +tm.s4["toto"] = 1999; +tm.s4["tatata"] = 1999; +tm.s6 = Color.Red; +tm.s7 = true + +let txt = JSON.stringify(tm) +let txtElem = document.createElement('textarea'); +txtElem.value = txt; + +document.body.appendChild(txtElem); + +let greeter = new Greeter("world"); + +let button = document.createElement('button'); +button.textContent = "Say Hello"; +button.onclick = function() { + alert(greeter.greet()); +} + +document.body.appendChild(button);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/playground3.ts Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,275 @@ +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ + +namespace VsolStuff222 { + export enum EnumMonth0 { + January, + February, + March + }; + + export class Message1 { + a: number; + b: string; + c: EnumMonth0; + d: boolean; + public StoneSerialize(): string { + let container: object = {}; + container['type'] = 'VsolStuff.Message1'; + container['value'] = this; + return JSON.stringify(container); + } + }; + + export class Message2 { + toto: string; + tata: Message1[]; + tutu: string[]; + titi: Map<string, string>; + lulu: Map<string, Message1>; + + public StoneSerialize(): string { + let container: object = {}; + container['type'] = 'VsolStuff.Message2'; + container['value'] = this; + return JSON.stringify(container); + } + }; +} + +function printf(value: any): void { + console.log(value) +} + +function main(): number { + + let msg1_0 = new VsolStuff.Message1(); + msg1_0.a = 42; + msg1_0.b = "Benjamin"; + msg1_0.c = VsolStuff.EnumMonth0.January; + msg1_0.d = true; + + let msg1_1 = new VsolStuff.Message1(); + msg1_1.a = 43; + msg1_1.b = "Sandrine"; + msg1_1.c = VsolStuff.EnumMonth0.March; + msg1_0.d = false; + + // std::string toto; + // std::vector<Message1> tata; + // std::vector<std::string> tutu; + // std::map<int32_t, std::string> titi; + // std::map<int32_t, Message1> lulu; + + let msg2_0 = new VsolStuff.Message2(); + msg2_0.toto = "Prout zizi"; + msg2_0.tata = new Array<VsolStuff.Message1>(); + msg2_0.tata.push(msg1_0); + msg2_0.tata.push(msg1_1); + msg2_0.tutu.push("Mercadet"); + msg2_0.tutu.push("Poisson");ing + msg2_0.titi["44"] = "key 44"; + msg2_0.titi["45"] = "key 45"; + msg2_0.lulu["54"] = msg1_1; + msg2_0.lulu["55"] = msg1_0; + let result:string = VsolStuff.StoneSerialize(msg2_0); + return 0; +} + +main() + +// string StoneSerialize_number(int32_t value) +// { + +// Json::Value result(value); +// return result; +// } + +// Json::Value StoneSerialize(double value) +// { +// Json::Value result(value); +// return result; +// } + +// Json::Value StoneSerialize(bool value) +// { +// Json::Value result(value); +// return result; +// } + +// Json::Value StoneSerialize(const std::string& value) +// { +// // the following is better than +// Json::Value result(value.data(),value.data()+value.size()); +// return result; +// } + +// template<typename T> +// Json::Value StoneSerialize(const std::map<std::string,T>& value) +// { +// Json::Value result(Json::objectValue); + +// for (std::map<std::string, T>::const_iterator it = value.cbegin(); +// it != value.cend(); ++it) +// { +// // it->first it->second +// result[it->first] = StoneSerialize(it->second); +// } +// return result; +// } + +// template<typename T> +// Json::Value StoneSerialize(const std::vector<T>& value) +// { +// Json::Value result(Json::arrayValue); +// for (size_t i = 0; i < value.size(); ++i) +// { +// result.append(StoneSerialize(value[i])); +// } +// return result; +// } + +// enum EnumMonth0 +// { +// January, +// February, +// March +// }; + +// std::string ToString(EnumMonth0 value) +// { +// switch(value) +// { +// case January: +// return "January"; +// case February: +// return "February"; +// case March: +// return "March"; +// default: +// { +// std::stringstream ss; +// ss << "Unrecognized EnumMonth0 value (" << static_cast<int64_t>(value) << ")"; +// throw std::runtime_error(ss.str()); +// } +// } +// } + +// void FromString(EnumMonth0& value, std::string strValue) +// { +// if (strValue == "January" || strValue == "EnumMonth0_January") +// { +// return January; +// } +// else if (strValue == "February" || strValue == "EnumMonth0_February") +// { +// return February; +// } +// #error Not implemented yet +// } + +// Json::Value StoneSerialize(const EnumMonth0& value) +// { +// return StoneSerialize(ToString(value)); +// } +// struct Message1 +// { +// int32_t a; +// std::string b; +// EnumMonth0 c; +// bool d; +// }; + +// struct Message2 +// { +// std::string toto; +// std::vector<Message1> tata; +// std::vector<std::string> tutu; +// std::map<std::string, std::string> titi; +// std::map<std::string, Message1> lulu; +// }; + +// Json::Value StoneSerialize(const Message1& value) +// { +// Json::Value result(Json::objectValue); +// result["a"] = StoneSerialize(value.a); +// result["b"] = StoneSerialize(value.b); +// result["c"] = StoneSerialize(value.c); +// result["d"] = StoneSerialize(value.d); +// return result; +// } + +// Json::Value StoneSerialize(const Message2& value) +// { +// Json::Value result(Json::objectValue); +// result["toto"] = StoneSerialize(value.toto); +// result["tata"] = StoneSerialize(value.tata); +// result["tutu"] = StoneSerialize(value.tutu); +// result["titi"] = StoneSerialize(value.titi); +// result["lulu"] = StoneSerialize(value.lulu); +// return result; +// } +// } + +// int main() +// { +// VsolStuff::Message1 msg1_0; +// msg1_0.a = 42; +// msg1_0.b = "Benjamin"; +// msg1_0.c = VsolStuff::January; +// msg1_0.d = true; + +// VsolStuff::Message1 msg1_1; +// msg1_1.a = 43; +// msg1_1.b = "Sandrine"; +// msg1_1.c = VsolStuff::March; +// msg1_0.d = false; + +// // std::string toto; +// // std::vector<Message1> tata; +// // std::vector<std::string> tutu; +// // std::map<int32_t, std::string> titi; +// // std::map<int32_t, Message1> lulu; + +// VsolStuff::Message2 msg2_0; +// msg2_0.toto = "Prout zizi"; +// msg2_0.tata.push_back(msg1_0); +// msg2_0.tata.push_back(msg1_1); +// msg2_0.tutu.push_back("Mercadet"); +// msg2_0.tutu.push_back("Poisson"); +// msg2_0.titi["44"] = "key 44"; +// msg2_0.titi["45"] = "key 45"; +// msg2_0.lulu["54"] = msg1_1; +// msg2_0.lulu["55"] = msg1_0; +// auto result = VsolStuff::StoneSerialize(msg2_0); +// auto resultStr = result.toStyledString(); + +// Json::Value readValue; + +// Json::CharReaderBuilder builder; +// Json::CharReader* reader = builder.newCharReader(); +// std::string errors; + +// bool ok = reader->parse( +// resultStr.c_str(), +// resultStr.c_str() + resultStr.size(), +// &readValue, +// &errors +// ); +// delete reader; + +// if (!ok) +// { +// std::stringstream ss; +// ss << "Json parsing error: " << errors; +// throw std::runtime_error(ss.str()); +// } +// std::cout << readValue.get("toto", "Default Value").asString() << std::endl; +// return 0; +// } + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/playground4.py Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,68 @@ +testYaml = """ +enum SomeEnum: + - january + - feb + +struct Message0: + a: string + +struct Message1: + a: string + b: int32 + c: vector<Message0> + d: SomeEnum = january + e: SomeEnum= january + f: SomeEnum=january + g: SomeEnum =january + + +# github.com/AlDanial/cloc +header2 : + cloc_version : 1.67 + elapsed_seconds : int32_t + +header : + cloc_version : 1.67 + elapsed_seconds : int32_t + cloc_url : vector<map<string,int32>> + n_files : 1 + n_lines : 3 + files_per_second : 221.393718659277 + lines_per_second : 664.181155977831 + report_file : IDL.idl.yaml +IDL : + nFiles: 1 + blank: 0 + comment: 2 + code: 1 +EnumSUM: + - aaa + - bbb + +SUM: + blank: 0 + comment: 2 + code: 1 + nFiles: 1 +""" + +import yaml + +b = yaml.load(testYaml) +print(b) + +c = { + 'enum SomeEnum': ['january', 'feb'], + 'struct Message0': {'a': 'string'}, + 'struct Message1': { + 'a': 'string', + 'b': 'int32', + 'c': 'vector<Message0>', + 'd': 'vector<map<string,int32>>', + 'e': 'SomeEnum= january', + 'f': 'SomeEnum=january', + 'g': 'SomeEnum =january' + }, +} + +print(c) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/runts.ps1 Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,63 @@ +# echo "+----------------------+" +# echo "| template.in.ts |" +# echo "+----------------------+" + +# tsc -t ES2015 .\template.in.ts; node .\template.in.js + +# echo "+----------------------+" +# echo "| playground.ts |" +# echo "+----------------------+" + +# tsc -t ES2015 .\playground.ts; node .\playground.js + +# echo "+----------------------+" +# echo "| playground3.ts |" +# echo "+----------------------+" + +# tsc -t ES2015 .\playground3.ts; node .\playground3.js + +echo "+----------------------+" +echo "| stonegen |" +echo "+----------------------+" + +if(-not (test-Path "build")) { + mkdir "build" +} + +echo "Generate the TS and CPP wrapper... (to build/)" +python stonegentool.py -o "." test_data/test1.yaml +if($LASTEXITCODE -ne 0) { + Write-Error ("Code generation failed!") + exit $LASTEXITCODE +} + +echo "Compile the TS wrapper to JS... (in build/)" +tsc --module commonjs --sourceMap -t ES2015 --outDir "build/" VsolMessages_generated.ts +if($LASTEXITCODE -ne 0) { + Write-Error ("Code compilation failed!") + exit $LASTEXITCODE +} + +echo "Compile the test app..." +tsc --module commonjs --sourceMap -t ES2015 --outDir "build/" test_stonegen.ts +if($LASTEXITCODE -ne 0) { + Write-Error ("Code compilation failed!") + exit $LASTEXITCODE +} + +browserify "build/test_stonegen.js" "build/VsolMessages_generated.js" -o "build_browser/test_stonegen_fused.js" + +cp .\test_stonegen.html .\build_browser\ + +echo "Run the test app..." +Push-Location +cd build_browser +node .\test_stonegen_fused.js +Pop-Location +if($LASTEXITCODE -ne 0) { + Write-Error ("Code execution failed!") + exit $LASTEXITCODE +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/test_stonegen.html Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,1 @@ +<script type="text/javascript" src="test_stonegen_fused.js"></script>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/test_stonegen.ts Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,206 @@ +import * as VsolMessages from "./VsolMessages_generated"; + +function TEST_StoneGen_SerializeComplex() { + let msg1_0 = new VsolMessages.Message1(); + msg1_0.a = 42; + msg1_0.b = "Benjamin"; + msg1_0.c = VsolMessages.EnumMonth0.January; + msg1_0.d = true; + let msg1_1 = new VsolMessages.Message1(); + msg1_1.a = 43; + msg1_1.b = "Sandrine"; + msg1_1.c = VsolMessages.EnumMonth0.March; + msg1_0.d = false; + let result1_0 = msg1_0.StoneSerialize(); + let resultStr1_0 = JSON.stringify(result1_0); + let result1_1 = msg1_1.StoneSerialize(); + let resultStr1_1 = JSON.stringify(result1_1); + // std::string toto; + // std::vector<Message1> tata; + // std::vector<std::string> tutu; + // std::map<int32_t, std::string> titi; + // std::map<int32_t, Message1> lulu; + let msg2_0 = new VsolMessages.Message2(); + msg2_0.toto = "Prout zizi"; + msg2_0.tata.push(msg1_0); + msg2_0.tata.push(msg1_1); + msg2_0.tutu.push("Mercadet"); + msg2_0.tutu.push("Poisson"); + msg2_0.titi["44"] = "key 44"; + msg2_0.titi["45"] = "key 45"; + msg2_0.lulu["54"] = msg1_1; + msg2_0.lulu["55"] = msg1_0; + let result2 = msg2_0.StoneSerialize(); + let resultStr2 = JSON.stringify(result2); + let refResult2 = `{ +"type" : "VsolMessages.Message2", +"value" : +{ + "lulu" : + { + "54" : + { + "a" : 43, + "b" : "Sandrine", + "c" : 2, + "d" : true + }, + "55" : + { + "a" : 42, + "b" : "Benjamin", + "c" : 0, + "d" : false + } + }, + "tata" : + [ + { + "a" : 42, + "b" : "Benjamin", + "c" : 0, + "d" : false + }, + { + "a" : 43, + "b" : "Sandrine", + "c" : 2, + "d" : true + } + ], + "titi" : + { + "44" : "key 44", + "45" : "key 45" + }, + "toto" : "Prout zizi", + "tutu" : + [ + "Mercadet", + "Poisson" + ] +} +} +`; + let refResult2Obj = JSON.parse(refResult2); + let resultStr2Obj = JSON.parse(resultStr2); + if (false) { + if (refResult2Obj !== resultStr2Obj) { + console.log("Results are different!"); + console.log(`refResult2Obj['value']['lulu']['54'] = ${refResult2Obj['value']['lulu']['54']}`); + console.log(`refResult2Obj['value']['lulu']['54']['a'] = ${refResult2Obj['value']['lulu']['54']['a']}`); + console.log("************************************************************"); + console.log("** REFERENCE OBJ **"); + console.log("************************************************************"); + console.log(refResult2Obj); + console.log("************************************************************"); + console.log("** ACTUAL OBJ **"); + console.log("************************************************************"); + console.log(resultStr2Obj); + console.log("************************************************************"); + console.log("** REFERENCE **"); + console.log("************************************************************"); + console.log(refResult2); + console.log("************************************************************"); + console.log("** ACTUAL **"); + console.log("************************************************************"); + console.log(resultStr2); + throw new Error("Wrong serialization"); + } + } + let refResultValue = JSON.parse(resultStr2); + console.log(refResultValue); +} +class MyDispatcher { + message1: VsolMessages.Message1; + message2: VsolMessages.Message2; + + HandleMessage1(value: VsolMessages.Message1) { + this.message1 = value; + return true; + } + HandleMessage2(value: VsolMessages.Message2) { + this.message2 = value; + return true; + } + HandleA(value) { + return true; + } + HandleB(value) { + return true; + } + HandleC(value) { + return true; + } +} +; +function TEST_StoneGen_DeserializeOkAndNok() { + let serializedMessage = `{ +"type" : "VsolMessages.Message2", +"value" : +{ + "lulu" : + { + "54" : + { + "a" : 43, + "b" : "Sandrine", + "c" : 2, + "d" : true + }, + "55" : + { + "a" : 42, + "b" : "Benjamin", + "c" : 0, + "d" : false + } + }, + "tata" : + [ + { + "a" : 42, + "b" : "Benjamin", + "c" : 0, + "d" : false + }, + { + "a" : 43, + "b" : "Sandrine", + "c" : 2, + "d" : true + } + ], + "titi" : + { + "44" : "key 44", + "45" : "key 45" + }, + "toto" : "Prout zizi", + "tutu" : + [ + "Mercadet", + "Poisson" + ] +} +}`; + let myDispatcher = new MyDispatcher(); + let ok = VsolMessages.StoneDispatchToHandler(serializedMessage, myDispatcher); + if (!ok) { + throw Error("Error when dispatching message!"); + } + if (myDispatcher.message1 != undefined) { + throw Error("(myDispatcher.Message1 != undefined)"); + } + if (myDispatcher.message2 == undefined) { + throw Error("(myDispatcher.Message2 == undefined)"); + } + console.log("TEST_StoneGen_DeserializeOkAndNok: OK!"); +} +function main() { + console.log("Entering main()"); + TEST_StoneGen_SerializeComplex(); + TEST_StoneGen_DeserializeOkAndNok(); + return 0; +} +console.log(`Exit code is: ${main()}`); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/Graveyard/tsconfig.json Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,22 @@ +{ + // "extends": "../../../../../orthanc-stone/Platforms/Wasm/tsconfig-stone", + "compilerOptions": { + // "outFile": "../../../WebApplication-build/to-embed/app.js", + // "module": "system", + // "sourceMap": false, + "lib": [ + "es2017", + "es2017", + "dom", + "dom.iterable" + ] + }, + "include": [ + // "commands/*.ts", + // "logger.ts", + // "app.ts", + // "main.ts", + // "ui.ts", + // "popup.ts" + ] +}
--- a/Resources/CodeGeneration/README.md Sat Feb 23 10:18:13 2019 +0100 +++ b/Resources/CodeGeneration/README.md Sat Feb 23 14:14:32 2019 +0100 @@ -8,3 +8,10 @@ - `npm install typescript` - `npm install tsify` +`testCppHandler` contains a C++ project that produces an executable +slurping a set of text files representing messages defined against +the `test_data/test1.yaml' schema and dumping them to `cout`. + +'testWasmIntegrated` contains a small Web app demonstrating the +interaction between TypeScript and C++ in WASM. +source ~/apps/emsdk/emsdk_env.sh \ No newline at end of file
--- a/Resources/CodeGeneration/playground.ts Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,259 +0,0 @@ -/* - 1 2 3 4 5 6 7 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -*/ - -namespace VsolStuff -{ - enum EnumMonth0 - { - January, - February, - March - }; - - // interface Serializer - // { - // Serialize(value: number): string; - // Serialize(value: string): string; - // Serialize(value: EnumMonth0): string; - // }; - function printf(value: any):void - { - console.log(value) - } - - // function StoneSerialize(value: string) : string; - // function StoneSerialize(value: number) : string; - // function StoneSerialize(value: EnumMonth0) : string; - function StoneSerialize<T>(value: T[]) : string; - - function StoneSerialize<T>(value: T[] | EnumMonth0) : string - { - let valueType = typeof value; - printf(`About to serialize value. Type is ${valueType}`) - printf(`About to serialize value. Type is ${typeof value}`) - return "Choucroute"; - } - - function main():number - { - enum Color {Red = 1, Green = 2, Blue = 4} - let color: Color = Color.Green; - printf("---------------------------"); - printf(`typeof color: ${typeof color}`); - printf("---------------------------"); - let colors: Color[] = [] - colors.push(Color.Green); - colors.push(Color.Red); - printf(`typeof colors: ${typeof colors}`); - printf(`Array.isArray(colors): ${Array.isArray(colors)}`); - printf("---------------------------"); - - - let toto:EnumMonth0[] = []; - - toto.push(EnumMonth0.February); - toto.push(EnumMonth0.March); - - printf(JSON.stringify(toto)); - - return 0; - - } - - main() - -// string StoneSerialize_number(int32_t value) -// { - -// Json::Value result(value); -// return result; -// } - -// Json::Value StoneSerialize(double value) -// { -// Json::Value result(value); -// return result; -// } - -// Json::Value StoneSerialize(bool value) -// { -// Json::Value result(value); -// return result; -// } - -// Json::Value StoneSerialize(const std::string& value) -// { -// // the following is better than -// Json::Value result(value.data(),value.data()+value.size()); -// return result; -// } - -// template<typename T> -// Json::Value StoneSerialize(const std::map<std::string,T>& value) -// { -// Json::Value result(Json::objectValue); - -// for (std::map<std::string, T>::const_iterator it = value.cbegin(); -// it != value.cend(); ++it) -// { -// // it->first it->second -// result[it->first] = StoneSerialize(it->second); -// } -// return result; -// } - -// template<typename T> -// Json::Value StoneSerialize(const std::vector<T>& value) -// { -// Json::Value result(Json::arrayValue); -// for (size_t i = 0; i < value.size(); ++i) -// { -// result.append(StoneSerialize(value[i])); -// } -// return result; -// } - -// enum EnumMonth0 -// { -// January, -// February, -// March -// }; - -// std::string ToString(EnumMonth0 value) -// { -// switch(value) -// { -// case January: -// return "January"; -// case February: -// return "February"; -// case March: -// return "March"; -// default: -// { -// std::stringstream ss; -// ss << "Unrecognized EnumMonth0 value (" << static_cast<int64_t>(value) << ")"; -// throw std::runtime_error(ss.str()); -// } -// } -// } - -// void FromString(EnumMonth0& value, std::string strValue) -// { -// if (strValue == "January" || strValue == "EnumMonth0_January") -// { -// return January; -// } -// else if (strValue == "February" || strValue == "EnumMonth0_February") -// { -// return February; -// } -// #error Not implemented yet -// } - -// Json::Value StoneSerialize(const EnumMonth0& value) -// { -// return StoneSerialize(ToString(value)); -// } -// struct Message1 -// { -// int32_t a; -// std::string b; -// EnumMonth0 c; -// bool d; -// }; - -// struct Message2 -// { -// std::string toto; -// std::vector<Message1> tata; -// std::vector<std::string> tutu; -// std::map<std::string, std::string> titi; -// std::map<std::string, Message1> lulu; -// }; - -// Json::Value StoneSerialize(const Message1& value) -// { -// Json::Value result(Json::objectValue); -// result["a"] = StoneSerialize(value.a); -// result["b"] = StoneSerialize(value.b); -// result["c"] = StoneSerialize(value.c); -// result["d"] = StoneSerialize(value.d); -// return result; -// } - -// Json::Value StoneSerialize(const Message2& value) -// { -// Json::Value result(Json::objectValue); -// result["toto"] = StoneSerialize(value.toto); -// result["tata"] = StoneSerialize(value.tata); -// result["tutu"] = StoneSerialize(value.tutu); -// result["titi"] = StoneSerialize(value.titi); -// result["lulu"] = StoneSerialize(value.lulu); -// return result; -// } -// } - -// int main() -// { -// VsolStuff::Message1 msg1_0; -// msg1_0.a = 42; -// msg1_0.b = "Benjamin"; -// msg1_0.c = VsolStuff::January; -// msg1_0.d = true; - -// VsolStuff::Message1 msg1_1; -// msg1_1.a = 43; -// msg1_1.b = "Sandrine"; -// msg1_1.c = VsolStuff::March; -// msg1_0.d = false; - -// // std::string toto; -// // std::vector<Message1> tata; -// // std::vector<std::string> tutu; -// // std::map<int32_t, std::string> titi; -// // std::map<int32_t, Message1> lulu; - -// VsolStuff::Message2 msg2_0; -// msg2_0.toto = "Prout zizi"; -// msg2_0.tata.push_back(msg1_0); -// msg2_0.tata.push_back(msg1_1); -// msg2_0.tutu.push_back("Mercadet"); -// msg2_0.tutu.push_back("Poisson"); -// msg2_0.titi["44"] = "key 44"; -// msg2_0.titi["45"] = "key 45"; -// msg2_0.lulu["54"] = msg1_1; -// msg2_0.lulu["55"] = msg1_0; -// auto result = VsolStuff::StoneSerialize(msg2_0); -// auto resultStr = result.toStyledString(); - -// Json::Value readValue; - -// Json::CharReaderBuilder builder; -// Json::CharReader* reader = builder.newCharReader(); -// std::string errors; - -// bool ok = reader->parse( -// resultStr.c_str(), -// resultStr.c_str() + resultStr.size(), -// &readValue, -// &errors -// ); -// delete reader; - -// if (!ok) -// { -// std::stringstream ss; -// ss << "Json parsing error: " << errors; -// throw std::runtime_error(ss.str()); -// } -// std::cout << readValue.get("toto", "Default Value").asString() << std::endl; -// return 0; -// } - - -} -
--- a/Resources/CodeGeneration/playground2.ts Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -class Greeter { - greeting: string; - constructor(message: string) { - this.greeting = message; - } - greet() { - return "Hello, " + this.greeting; - } -} -enum Color { - Red, - Green, - Blue, -}; - -function ColorToString(value: Color) -{ - switch (value) - { - case Color.Red: - return "Red"; - case Color.Green: - return "Green"; - case Color.Blue: - return "Blue"; - default: - throw new Error(`Unrecognized Color value(${value})`); - } -} - -let color: Color = Color.Red; - -document.body.textContent = "<p>---------------------</p>" -document.body.textContent += "<p>********************************</p>" - -class TestMessage { - s1: string; - s2: Array<string>; - s3: Array<Array<string>>; - s4: Map<string, number>; - s5: Map<number, Array<string>>; - s6: Color; - s7: boolean; -} - -let tm = new TestMessage(); -tm.s2 = new Array<string>() -tm.s2.push("toto"); -tm.s2.push("toto2"); -tm.s2.push("toto3"); -tm.s4 = new Map<string, number>(); -tm.s4["toto"] = 42; -tm.s4["toto"] = 1999; -tm.s4["tatata"] = 1999; -tm.s6 = Color.Red; -tm.s7 = true - -let txt = JSON.stringify(tm) -let txtElem = document.createElement('textarea'); -txtElem.value = txt; - -document.body.appendChild(txtElem); - -let greeter = new Greeter("world"); - -let button = document.createElement('button'); -button.textContent = "Say Hello"; -button.onclick = function() { - alert(greeter.greet()); -} - -document.body.appendChild(button);
--- a/Resources/CodeGeneration/playground3.ts Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,275 +0,0 @@ -/* - 1 2 3 4 5 6 7 -12345678901234567890123456789012345678901234567890123456789012345678901234567890 -*/ - -namespace VsolStuff222 { - export enum EnumMonth0 { - January, - February, - March - }; - - export class Message1 { - a: number; - b: string; - c: EnumMonth0; - d: boolean; - public StoneSerialize(): string { - let container: object = {}; - container['type'] = 'VsolStuff.Message1'; - container['value'] = this; - return JSON.stringify(container); - } - }; - - export class Message2 { - toto: string; - tata: Message1[]; - tutu: string[]; - titi: Map<string, string>; - lulu: Map<string, Message1>; - - public StoneSerialize(): string { - let container: object = {}; - container['type'] = 'VsolStuff.Message2'; - container['value'] = this; - return JSON.stringify(container); - } - }; -} - -function printf(value: any): void { - console.log(value) -} - -function main(): number { - - let msg1_0 = new VsolStuff.Message1(); - msg1_0.a = 42; - msg1_0.b = "Benjamin"; - msg1_0.c = VsolStuff.EnumMonth0.January; - msg1_0.d = true; - - let msg1_1 = new VsolStuff.Message1(); - msg1_1.a = 43; - msg1_1.b = "Sandrine"; - msg1_1.c = VsolStuff.EnumMonth0.March; - msg1_0.d = false; - - // std::string toto; - // std::vector<Message1> tata; - // std::vector<std::string> tutu; - // std::map<int32_t, std::string> titi; - // std::map<int32_t, Message1> lulu; - - let msg2_0 = new VsolStuff.Message2(); - msg2_0.toto = "Prout zizi"; - msg2_0.tata = new Array<VsolStuff.Message1>(); - msg2_0.tata.push(msg1_0); - msg2_0.tata.push(msg1_1); - msg2_0.tutu.push("Mercadet"); - msg2_0.tutu.push("Poisson");ing - msg2_0.titi["44"] = "key 44"; - msg2_0.titi["45"] = "key 45"; - msg2_0.lulu["54"] = msg1_1; - msg2_0.lulu["55"] = msg1_0; - let result:string = VsolStuff.StoneSerialize(msg2_0); - return 0; -} - -main() - -// string StoneSerialize_number(int32_t value) -// { - -// Json::Value result(value); -// return result; -// } - -// Json::Value StoneSerialize(double value) -// { -// Json::Value result(value); -// return result; -// } - -// Json::Value StoneSerialize(bool value) -// { -// Json::Value result(value); -// return result; -// } - -// Json::Value StoneSerialize(const std::string& value) -// { -// // the following is better than -// Json::Value result(value.data(),value.data()+value.size()); -// return result; -// } - -// template<typename T> -// Json::Value StoneSerialize(const std::map<std::string,T>& value) -// { -// Json::Value result(Json::objectValue); - -// for (std::map<std::string, T>::const_iterator it = value.cbegin(); -// it != value.cend(); ++it) -// { -// // it->first it->second -// result[it->first] = StoneSerialize(it->second); -// } -// return result; -// } - -// template<typename T> -// Json::Value StoneSerialize(const std::vector<T>& value) -// { -// Json::Value result(Json::arrayValue); -// for (size_t i = 0; i < value.size(); ++i) -// { -// result.append(StoneSerialize(value[i])); -// } -// return result; -// } - -// enum EnumMonth0 -// { -// January, -// February, -// March -// }; - -// std::string ToString(EnumMonth0 value) -// { -// switch(value) -// { -// case January: -// return "January"; -// case February: -// return "February"; -// case March: -// return "March"; -// default: -// { -// std::stringstream ss; -// ss << "Unrecognized EnumMonth0 value (" << static_cast<int64_t>(value) << ")"; -// throw std::runtime_error(ss.str()); -// } -// } -// } - -// void FromString(EnumMonth0& value, std::string strValue) -// { -// if (strValue == "January" || strValue == "EnumMonth0_January") -// { -// return January; -// } -// else if (strValue == "February" || strValue == "EnumMonth0_February") -// { -// return February; -// } -// #error Not implemented yet -// } - -// Json::Value StoneSerialize(const EnumMonth0& value) -// { -// return StoneSerialize(ToString(value)); -// } -// struct Message1 -// { -// int32_t a; -// std::string b; -// EnumMonth0 c; -// bool d; -// }; - -// struct Message2 -// { -// std::string toto; -// std::vector<Message1> tata; -// std::vector<std::string> tutu; -// std::map<std::string, std::string> titi; -// std::map<std::string, Message1> lulu; -// }; - -// Json::Value StoneSerialize(const Message1& value) -// { -// Json::Value result(Json::objectValue); -// result["a"] = StoneSerialize(value.a); -// result["b"] = StoneSerialize(value.b); -// result["c"] = StoneSerialize(value.c); -// result["d"] = StoneSerialize(value.d); -// return result; -// } - -// Json::Value StoneSerialize(const Message2& value) -// { -// Json::Value result(Json::objectValue); -// result["toto"] = StoneSerialize(value.toto); -// result["tata"] = StoneSerialize(value.tata); -// result["tutu"] = StoneSerialize(value.tutu); -// result["titi"] = StoneSerialize(value.titi); -// result["lulu"] = StoneSerialize(value.lulu); -// return result; -// } -// } - -// int main() -// { -// VsolStuff::Message1 msg1_0; -// msg1_0.a = 42; -// msg1_0.b = "Benjamin"; -// msg1_0.c = VsolStuff::January; -// msg1_0.d = true; - -// VsolStuff::Message1 msg1_1; -// msg1_1.a = 43; -// msg1_1.b = "Sandrine"; -// msg1_1.c = VsolStuff::March; -// msg1_0.d = false; - -// // std::string toto; -// // std::vector<Message1> tata; -// // std::vector<std::string> tutu; -// // std::map<int32_t, std::string> titi; -// // std::map<int32_t, Message1> lulu; - -// VsolStuff::Message2 msg2_0; -// msg2_0.toto = "Prout zizi"; -// msg2_0.tata.push_back(msg1_0); -// msg2_0.tata.push_back(msg1_1); -// msg2_0.tutu.push_back("Mercadet"); -// msg2_0.tutu.push_back("Poisson"); -// msg2_0.titi["44"] = "key 44"; -// msg2_0.titi["45"] = "key 45"; -// msg2_0.lulu["54"] = msg1_1; -// msg2_0.lulu["55"] = msg1_0; -// auto result = VsolStuff::StoneSerialize(msg2_0); -// auto resultStr = result.toStyledString(); - -// Json::Value readValue; - -// Json::CharReaderBuilder builder; -// Json::CharReader* reader = builder.newCharReader(); -// std::string errors; - -// bool ok = reader->parse( -// resultStr.c_str(), -// resultStr.c_str() + resultStr.size(), -// &readValue, -// &errors -// ); -// delete reader; - -// if (!ok) -// { -// std::stringstream ss; -// ss << "Json parsing error: " << errors; -// throw std::runtime_error(ss.str()); -// } -// std::cout << readValue.get("toto", "Default Value").asString() << std::endl; -// return 0; -// } - - -} -
--- a/Resources/CodeGeneration/playground4.py Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -testYaml = """ -enum SomeEnum: - - january - - feb - -struct Message0: - a: string - -struct Message1: - a: string - b: int32 - c: vector<Message0> - d: SomeEnum = january - e: SomeEnum= january - f: SomeEnum=january - g: SomeEnum =january - - -# github.com/AlDanial/cloc -header2 : - cloc_version : 1.67 - elapsed_seconds : int32_t - -header : - cloc_version : 1.67 - elapsed_seconds : int32_t - cloc_url : vector<map<string,int32>> - n_files : 1 - n_lines : 3 - files_per_second : 221.393718659277 - lines_per_second : 664.181155977831 - report_file : IDL.idl.yaml -IDL : - nFiles: 1 - blank: 0 - comment: 2 - code: 1 -EnumSUM: - - aaa - - bbb - -SUM: - blank: 0 - comment: 2 - code: 1 - nFiles: 1 -""" - -import yaml - -b = yaml.load(testYaml) -print(b) - -c = { - 'enum SomeEnum': ['january', 'feb'], - 'struct Message0': {'a': 'string'}, - 'struct Message1': { - 'a': 'string', - 'b': 'int32', - 'c': 'vector<Message0>', - 'd': 'vector<map<string,int32>>', - 'e': 'SomeEnum= january', - 'f': 'SomeEnum=january', - 'g': 'SomeEnum =january' - }, -} - -print(c) \ No newline at end of file
--- a/Resources/CodeGeneration/runts.ps1 Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -# echo "+----------------------+" -# echo "| template.in.ts |" -# echo "+----------------------+" - -# tsc -t ES2015 .\template.in.ts; node .\template.in.js - -# echo "+----------------------+" -# echo "| playground.ts |" -# echo "+----------------------+" - -# tsc -t ES2015 .\playground.ts; node .\playground.js - -# echo "+----------------------+" -# echo "| playground3.ts |" -# echo "+----------------------+" - -# tsc -t ES2015 .\playground3.ts; node .\playground3.js - -echo "+----------------------+" -echo "| stonegen |" -echo "+----------------------+" - -if(-not (test-Path "build")) { - mkdir "build" -} - -echo "Generate the TS and CPP wrapper... (to build/)" -python stonegentool.py -o "." test_data/test1.yaml -if($LASTEXITCODE -ne 0) { - Write-Error ("Code generation failed!") - exit $LASTEXITCODE -} - -echo "Compile the TS wrapper to JS... (in build/)" -tsc --module commonjs --sourceMap -t ES2015 --outDir "build/" VsolMessages_generated.ts -if($LASTEXITCODE -ne 0) { - Write-Error ("Code compilation failed!") - exit $LASTEXITCODE -} - -echo "Compile the test app..." -tsc --module commonjs --sourceMap -t ES2015 --outDir "build/" test_stonegen.ts -if($LASTEXITCODE -ne 0) { - Write-Error ("Code compilation failed!") - exit $LASTEXITCODE -} - -browserify "build/test_stonegen.js" "build/VsolMessages_generated.js" -o "build_browser/test_stonegen_fused.js" - -cp .\test_stonegen.html .\build_browser\ - -echo "Run the test app..." -Push-Location -cd build_browser -node .\test_stonegen_fused.js -Pop-Location -if($LASTEXITCODE -ne 0) { - Write-Error ("Code execution failed!") - exit $LASTEXITCODE -} - - -
--- a/Resources/CodeGeneration/template.in.h Sat Feb 23 10:18:13 2019 +0100 +++ b/Resources/CodeGeneration/template.in.h Sat Feb 23 14:14:32 2019 +0100 @@ -1,6 +1,7 @@ /* 1 2 3 4 5 6 7 12345678901234567890123456789012345678901234567890123456789012345678901234567890 + */ #include <iostream> @@ -72,7 +73,33 @@ Json::Value result(value.data(),value.data()+value.size()); return result; } - + + std::string MakeIndent(int indent) + { + char* txt = reinterpret_cast<char*>(malloc(indent+1)); // NO EXCEPTION BELOW!!!!!!!!!!!! + for(size_t i = 0; i < indent; ++i) + txt[i] = ' '; + txt[indent] = 0; + std::string retVal(txt); + free(txt); // NO EXCEPTION ABOVE !!!!!!!!!! + return retVal; + } + + // generic dumper + template<typename T> + std::ostream& StoneDumpValue(std::ostream& out, const T& value, int indent) + { + out << MakeIndent(indent) << value; + return out; + } + + // string dumper + std::ostream& StoneDumpValue(std::ostream& out, const std::string& value, int indent) + { + out << MakeIndent(indent) << "\"" << value << "\""; + return out; + } + /** Throws in case of problem */ template<typename T> void _StoneDeserializeValue( @@ -108,6 +135,20 @@ return result; } + template<typename T> + std::ostream& StoneDumpValue(std::ostream& out, const std::map<std::string,T>& value, int indent) + { + out << MakeIndent(indent) << "{\n"; + for (std::map<std::string, T>::const_iterator it = value.cbegin(); + it != value.cend(); ++it) + { + out << MakeIndent(indent+2) << "\"" << it->first << "\" : "; + StoneDumpValue(out, it->second, indent+2); + } + out << MakeIndent(indent) << "}\n"; + return out; + } + /** Throws in case of problem */ template<typename T> void _StoneDeserializeValue( @@ -134,6 +175,18 @@ return result; } + template<typename T> + std::ostream& StoneDumpValue(std::ostream& out, const std::vector<T>& value, int indent) + { + out << MakeIndent(indent) << "[\n"; + for (size_t i = 0; i < value.size(); ++i) + { + StoneDumpValue(out, value[i], indent+2); + } + out << MakeIndent(indent) << "]\n"; + return out; + } + void StoneCheckSerializedValueTypeGeneric(const Json::Value& value) { if ((!value.isMember("type")) || (!value["type"].isString())) @@ -177,6 +230,16 @@ { return Json::Value(static_cast<int64_t>(value)); } + + std::ostream& StoneDumpValue(std::ostream& out, const {{enum['name']}}& value, int indent = 0) + { +{% for key in enum['fields']%} if( value == {{key}}) + { + out << MakeIndent(indent) << "{{key}}" << std::endl; + } +{%endfor%} return out; + } + {%endfor%} {% for struct in structs%} #ifdef _MSC_VER @@ -208,6 +271,17 @@ return result; } + std::ostream& StoneDumpValue(std::ostream& out, const {{struct['name']}}& value, int indent = 0) + { + out << MakeIndent(indent) << "{\n"; +{% for key in struct['fields']%} out << MakeIndent(indent) << "{{key}}:\n"; + StoneDumpValue(out, value.{{key}},indent+2); + out << "\n"; +{% endfor %} + out << MakeIndent(indent) << "}\n"; + return out; + } + void StoneDeserialize({{struct['name']}}& destValue, const Json::Value& value) { StoneCheckSerializedValueType(value, "{{rootName}}.{{struct['name']}}"); @@ -230,7 +304,7 @@ #pragma region Dispatching code #endif //_MSC_VER - class IDispatcher + class IHandler { public: {% for struct in structs%} virtual bool Handle(const {{struct['name']}}& value) = 0; @@ -238,7 +312,7 @@ /** Service function for StoneDispatchToHandler */ bool StoneDispatchJsonToHandler( - const Json::Value& jsonValue, IDispatcher* dispatcher) + const Json::Value& jsonValue, IHandler* handler) { StoneCheckSerializedValueTypeGeneric(jsonValue); std::string type = jsonValue["type"].asString(); @@ -251,7 +325,7 @@ { {{struct['name']}} value; _StoneDeserializeValue(value, jsonValue["value"]); - return dispatcher->Handle(value); + return handler->Handle(value); } {% endfor %} else { @@ -259,8 +333,8 @@ } } - /** Takes a serialized type and passes this to the dispatcher */ - bool StoneDispatchToHandler(std::string strValue, IDispatcher* dispatcher) + /** Takes a serialized type and passes this to the handler */ + bool StoneDispatchToHandler(std::string strValue, IHandler* handler) { Json::Value readValue; @@ -283,7 +357,7 @@ ss << "Jsoncpp parsing error: " << errors; throw std::runtime_error(ss.str()); } - return StoneDispatchJsonToHandler(readValue, dispatcher); + return StoneDispatchJsonToHandler(readValue, handler); } #ifdef _MSC_VER
--- a/Resources/CodeGeneration/template.in.ts Sat Feb 23 10:18:13 2019 +0100 +++ b/Resources/CodeGeneration/template.in.ts Sat Feb 23 14:14:32 2019 +0100 @@ -50,7 +50,7 @@ public StoneSerialize(): string { let container: object = {}; - container['type'] = '{{rWholootName}}.{{struct['name']}}'; + container['type'] = '{{rootName}}.{{struct['name']}}'; container['value'] = this; return JSON.stringify(container); } @@ -66,14 +66,14 @@ {% endfor %} -export interface IDispatcher { +export interface IHandler { {% for struct in structs%} Handle{{struct['name']}}(value: {{struct['name']}}): boolean; {% endfor %} }; /** Service function for StoneDispatchToHandler */ export function StoneDispatchJsonToHandler( - jsonValue: any, dispatcher: IDispatcher): boolean + jsonValue: any, handler: IHandler): boolean { StoneCheckSerializedValueTypeGeneric(jsonValue); let type: string = jsonValue["type"]; @@ -85,7 +85,7 @@ {% for struct in structs%} else if (type == "{{rootName}}.{{struct['name']}}") { let value = jsonValue["value"] as {{struct['name']}}; - return dispatcher.Handle{{struct['name']}}(value); + return handler.Handle{{struct['name']}}(value); } {% endfor %} else @@ -94,9 +94,9 @@ } } -/** Takes a serialized type and passes this to the dispatcher */ +/** Takes a serialized type and passes this to the handler */ export function StoneDispatchToHandler( - strValue: string, dispatcher: IDispatcher): boolean + strValue: string, handler: IHandler): boolean { // console.//log("+------------------------------------------------+"); // console.//log("| StoneDispatchToHandler |"); @@ -104,5 +104,5 @@ // console.//log("strValue = "); // console.//log(strValue); let jsonValue: any = JSON.parse(strValue) - return StoneDispatchJsonToHandler(jsonValue, dispatcher); + return StoneDispatchJsonToHandler(jsonValue, handler); }
--- a/Resources/CodeGeneration/testCppHandler/CMakeLists.txt Sat Feb 23 10:18:13 2019 +0100 +++ b/Resources/CodeGeneration/testCppHandler/CMakeLists.txt Sat Feb 23 14:14:32 2019 +0100 @@ -2,16 +2,21 @@ project(testCppHandler) +set(testCppHandler_Codegen_Deps + ${CMAKE_CURRENT_LIST_DIR}/../test_data/test1.yaml + ${CMAKE_CURRENT_LIST_DIR}/../template.in.h +) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/VsolMessages_generated.hpp COMMAND python ${CMAKE_CURRENT_LIST_DIR}/../stonegentool.py -o ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/../test_data/test1.yaml - DEPENDS ${CMAKE_CURRENT_LIST_DIR}/../test_data/test1.yaml + DEPENDS ${testCppHandler_Codegen_Deps} ) include(${CMAKE_BINARY_DIR}/conanbuildinfo_multi.cmake) conan_basic_setup() -add_executable(testCppHandler main.cpp ${CMAKE_CURRENT_BINARY_DIR}/VsolMessages_generated.hpp) +add_executable(testCppHandler main.cpp OsDumpers.hpp ${CMAKE_CURRENT_BINARY_DIR}/VsolMessages_generated.hpp ${testCppHandler_Codegen_Deps}) target_include_directories(testCppHandler PUBLIC ${CMAKE_BINARY_DIR})
--- a/Resources/CodeGeneration/testCppHandler/main.cpp Sat Feb 23 10:18:13 2019 +0100 +++ b/Resources/CodeGeneration/testCppHandler/main.cpp Sat Feb 23 14:14:32 2019 +0100 @@ -1,18 +1,19 @@ -#include <string> -#include <filesystem> -#include <regex> -using namespace std; -namespace fs = std::filesystem; +#include <string> +#include <fstream> +#include <filesystem> +#include <regex> +using namespace std; +namespace fs = std::filesystem; #include <boost/program_options.hpp> -using namespace boost::program_options; - -#include "VsolMessages_generated.hpp" - -/** -Transforms `str` by replacing occurrences of `oldStr` with `newStr`, using -plain text (*not* regular expressions.) -*/ +using namespace boost::program_options; + +#include "VsolMessages_generated.hpp" + +/** +Transforms `str` by replacing occurrences of `oldStr` with `newStr`, using +plain text (*not* regular expressions.) +*/ static inline void ReplaceInString( string& str, const std::string& oldStr, @@ -23,23 +24,76 @@ str.replace(pos, oldStr.length(), newStr); pos += newStr.length(); } -} - -int main(int argc, char** argv) -{ - try - { - string pattern; - +} + +string SlurpFile(const string& fileName) +{ + ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate); + + ifstream::pos_type fileSize = ifs.tellg(); + ifs.seekg(0, ios::beg); + + vector<char> bytes(fileSize); + ifs.read(bytes.data(), fileSize); + + return string(bytes.data(), fileSize); +} + +class MyHandler : public VsolMessages::IHandler +{ +public: + virtual bool Handle(const VsolMessages::A& value) override + { + VsolMessages::StoneDumpValue(cout, value); + return true; + } + virtual bool Handle(const VsolMessages::B& value) override + { + VsolMessages::StoneDumpValue(cout, value); + return true; + } + virtual bool Handle(const VsolMessages::C& value) override + { + VsolMessages::StoneDumpValue(cout, value); + return true; + } + virtual bool Handle(const VsolMessages::Message1& value) override + { + VsolMessages::StoneDumpValue(cout, value); + return true; + } + virtual bool Handle(const VsolMessages::Message2& value) override + { + VsolMessages::StoneDumpValue(cout, value); + return true; + } +}; + +template<typename T> +void ProcessPath(T filePath) +{ + cout << "+--------------------------------------------+\n"; + cout << "| Processing: " << filePath.path().string() << "\n"; + cout << "+--------------------------------------------+\n"; + MyHandler handler; + auto contents = SlurpFile(filePath.path().string()); + VsolMessages::StoneDispatchToHandler(contents, &handler); +} + +int main(int argc, char** argv) +{ + try + { + options_description desc("Allowed options"); desc.add_options() // First parameter describes option name/short name // The second is parameter to option // The third is description ("help,h", "print usage message") - ("pattern,p", value(&pattern), "pattern for input") - ; - + ("pattern,p", value<string>(), "pattern for input") + ; + variables_map vm; store(parse_command_line(argc, argv, desc), vm); @@ -47,26 +101,39 @@ { cout << desc << "\n"; return 0; - } - - // tranform globbing pattern into regex - // we should deal with -, ., *... - string regexPatternStr = pattern; - regex regexPattern(regexPatternStr); - - for (auto& p : fs::directory_iterator(".")) - { - if (regex_match(p.path().string(), regexPattern)) - std::cout << "\"" << p << "\" is a match\n"; - else - std::cout << "\"" << p << "\" is *not* a match\n"; - } - return 0; - - - } + } + + notify(vm); + + string pattern = vm["pattern"].as<string>(); + + // tranform globbing pattern into regex + // we should deal with -, ., *... + string regexPatternStr = pattern; + cout << "Pattern is: " << regexPatternStr << endl; + ReplaceInString(regexPatternStr, "\\", "\\\\"); + ReplaceInString(regexPatternStr, "-", "\\-"); + ReplaceInString(regexPatternStr, ".", "\\."); + ReplaceInString(regexPatternStr, "*", ".*"); + ReplaceInString(regexPatternStr, "?", "."); + cout << "Corresponding regex is: " << regexPatternStr << endl; + + regex regexPattern(regexPatternStr); + + for (auto& p : fs::directory_iterator(".")) + { + auto fileName = p.path().filename().string(); + if (regex_match(fileName, regexPattern)) + { + ProcessPath(p); + } + } + return 0; + + + } catch (exception& e) { cerr << e.what() << "\n"; - } + } } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/testCppHandler/test_data/test_Message2.json Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,40 @@ +{ + "type": "VsolMessages.Message2", + "value": { + "tata": [ + { + "a": 42, + "b": "Benjamin", + "c": 0, + "d": false + }, + { + "a": 43, + "b": "Sandrine", + "c": 2 + } + ], + "tutu": [ + "Mercadet", + "Poisson" + ], + "titi": { + "44": "key 44", + "45": "key 45" + }, + "lulu": { + "54": { + "a": 43, + "b": "Sandrine", + "c": 2 + }, + "55": { + "a": 42, + "b": "Benjamin", + "c": 0, + "d": false + } + }, + "toto": "Prout zizi" + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/testWasmIntegrated/CMakeLists.txt Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 2.8) + +project(testWasmIntegratedCpp) + +set(testWasmIntegratedCpp_Codegen_Deps + ${CMAKE_CURRENT_LIST_DIR}/testWasmIntegratedCpp_api.yaml + ${CMAKE_CURRENT_LIST_DIR}/../template.in.h + ${CMAKE_CURRENT_LIST_DIR}/../template.in.ts +) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/testWasmIntegratedCpp_generated.hpp ${CMAKE_CURRENT_BINARY_DIR}/testWasmIntegratedCpp_generated.ts + COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/../stonegentool.py -o ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/../test_data/testWasmIntegratedCpp_api.yaml + DEPENDS ${testCppHandler_Codegen_Deps} +) + +add_library(testWasmIntegratedCpp main.cpp ${CMAKE_CURRENT_BINARY_DIR}/testWasmIntegratedCpp_generated.hpp ${testCppHandler_Codegen_Deps}) + +target_include_directories(testWasmIntegratedCpp PUBLIC ${CMAKE_BINARY_DIR}) + +set_property(TARGET testWasmIntegratedCpp PROPERTY CXX_STANDARD 11) + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/testWasmIntegrated/build.sh Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,33 @@ +#!/bin/bash + +set -e + +mkdir -p build-wasm +cd build-wasm + +# shellcheck source="$HOME/apps/emsdk/emsdk_env.sh" +source "$HOME/apps/emsdk/emsdk_env.sh" +cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_WASM=ON .. + +ninja + +echo + +cd .. + +mkdir -p + +# compile TS to JS +tsc --module commonjs --sourceMap -t ES2015 --outDir "build-tsc/" build-wasm/testWasmIntegratedCpp_generated.ts testWasmIntegrated.ts + +# bundle all JS files to final build dir +browserify "build-wasm/testWasmIntegratedCpp.js" "build-tsc/testWasmIntegratedCpp_generated.js" "build-tsc/testWasmIntegrated.js" -o "testWasmIntegratedApp.js" + +# copy HTML start page to output dir +cp index.html build-final/ + +# copy WASM binary to output dir +cp build-wasm/testWasmIntegratedCpp.wasm build-final/ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/CodeGeneration/testWasmIntegrated/main.cpp Sat Feb 23 14:14:32 2019 +0100 @@ -0,0 +1,6 @@ +#include <iostream> + +int main() +{ + std::cout << "Hello world from testWasmIntegrated!" << std::endl; +} \ No newline at end of file
--- a/Resources/CodeGeneration/test_stonegen.html Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -<script type="text/javascript" src="test_stonegen_fused.js"></script>
--- a/Resources/CodeGeneration/test_stonegen.ts Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,206 +0,0 @@ -import * as VsolMessages from "./VsolMessages_generated"; - -function TEST_StoneGen_SerializeComplex() { - let msg1_0 = new VsolMessages.Message1(); - msg1_0.a = 42; - msg1_0.b = "Benjamin"; - msg1_0.c = VsolMessages.EnumMonth0.January; - msg1_0.d = true; - let msg1_1 = new VsolMessages.Message1(); - msg1_1.a = 43; - msg1_1.b = "Sandrine"; - msg1_1.c = VsolMessages.EnumMonth0.March; - msg1_0.d = false; - let result1_0 = msg1_0.StoneSerialize(); - let resultStr1_0 = JSON.stringify(result1_0); - let result1_1 = msg1_1.StoneSerialize(); - let resultStr1_1 = JSON.stringify(result1_1); - // std::string toto; - // std::vector<Message1> tata; - // std::vector<std::string> tutu; - // std::map<int32_t, std::string> titi; - // std::map<int32_t, Message1> lulu; - let msg2_0 = new VsolMessages.Message2(); - msg2_0.toto = "Prout zizi"; - msg2_0.tata.push(msg1_0); - msg2_0.tata.push(msg1_1); - msg2_0.tutu.push("Mercadet"); - msg2_0.tutu.push("Poisson"); - msg2_0.titi["44"] = "key 44"; - msg2_0.titi["45"] = "key 45"; - msg2_0.lulu["54"] = msg1_1; - msg2_0.lulu["55"] = msg1_0; - let result2 = msg2_0.StoneSerialize(); - let resultStr2 = JSON.stringify(result2); - let refResult2 = `{ -"type" : "VsolMessages.Message2", -"value" : -{ - "lulu" : - { - "54" : - { - "a" : 43, - "b" : "Sandrine", - "c" : 2, - "d" : true - }, - "55" : - { - "a" : 42, - "b" : "Benjamin", - "c" : 0, - "d" : false - } - }, - "tata" : - [ - { - "a" : 42, - "b" : "Benjamin", - "c" : 0, - "d" : false - }, - { - "a" : 43, - "b" : "Sandrine", - "c" : 2, - "d" : true - } - ], - "titi" : - { - "44" : "key 44", - "45" : "key 45" - }, - "toto" : "Prout zizi", - "tutu" : - [ - "Mercadet", - "Poisson" - ] -} -} -`; - let refResult2Obj = JSON.parse(refResult2); - let resultStr2Obj = JSON.parse(resultStr2); - if (false) { - if (refResult2Obj !== resultStr2Obj) { - console.log("Results are different!"); - console.log(`refResult2Obj['value']['lulu']['54'] = ${refResult2Obj['value']['lulu']['54']}`); - console.log(`refResult2Obj['value']['lulu']['54']['a'] = ${refResult2Obj['value']['lulu']['54']['a']}`); - console.log("************************************************************"); - console.log("** REFERENCE OBJ **"); - console.log("************************************************************"); - console.log(refResult2Obj); - console.log("************************************************************"); - console.log("** ACTUAL OBJ **"); - console.log("************************************************************"); - console.log(resultStr2Obj); - console.log("************************************************************"); - console.log("** REFERENCE **"); - console.log("************************************************************"); - console.log(refResult2); - console.log("************************************************************"); - console.log("** ACTUAL **"); - console.log("************************************************************"); - console.log(resultStr2); - throw new Error("Wrong serialization"); - } - } - let refResultValue = JSON.parse(resultStr2); - console.log(refResultValue); -} -class MyDispatcher { - message1: VsolMessages.Message1; - message2: VsolMessages.Message2; - - HandleMessage1(value: VsolMessages.Message1) { - this.message1 = value; - return true; - } - HandleMessage2(value: VsolMessages.Message2) { - this.message2 = value; - return true; - } - HandleA(value) { - return true; - } - HandleB(value) { - return true; - } - HandleC(value) { - return true; - } -} -; -function TEST_StoneGen_DeserializeOkAndNok() { - let serializedMessage = `{ -"type" : "VsolMessages.Message2", -"value" : -{ - "lulu" : - { - "54" : - { - "a" : 43, - "b" : "Sandrine", - "c" : 2, - "d" : true - }, - "55" : - { - "a" : 42, - "b" : "Benjamin", - "c" : 0, - "d" : false - } - }, - "tata" : - [ - { - "a" : 42, - "b" : "Benjamin", - "c" : 0, - "d" : false - }, - { - "a" : 43, - "b" : "Sandrine", - "c" : 2, - "d" : true - } - ], - "titi" : - { - "44" : "key 44", - "45" : "key 45" - }, - "toto" : "Prout zizi", - "tutu" : - [ - "Mercadet", - "Poisson" - ] -} -}`; - let myDispatcher = new MyDispatcher(); - let ok = VsolMessages.StoneDispatchToHandler(serializedMessage, myDispatcher); - if (!ok) { - throw Error("Error when dispatching message!"); - } - if (myDispatcher.message1 != undefined) { - throw Error("(myDispatcher.Message1 != undefined)"); - } - if (myDispatcher.message2 == undefined) { - throw Error("(myDispatcher.Message2 == undefined)"); - } - console.log("TEST_StoneGen_DeserializeOkAndNok: OK!"); -} -function main() { - console.log("Entering main()"); - TEST_StoneGen_SerializeComplex(); - TEST_StoneGen_DeserializeOkAndNok(); - return 0; -} -console.log(`Exit code is: ${main()}`); \ No newline at end of file
--- a/Resources/CodeGeneration/tsconfig.json Sat Feb 23 10:18:13 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -{ - // "extends": "../../../../../orthanc-stone/Platforms/Wasm/tsconfig-stone", - "compilerOptions": { - // "outFile": "../../../WebApplication-build/to-embed/app.js", - // "module": "system", - // "sourceMap": false, - "lib": [ - "es2017", - "es2017", - "dom", - "dom.iterable" - ] - }, - "include": [ - // "commands/*.ts", - // "logger.ts", - // "app.ts", - // "main.ts", - // "ui.ts", - // "popup.ts" - ] -}