├── .gitignore ├── examples ├── 1-Hello-World.cpp ├── 40-Popen.cpp ├── 56-encoder-hex.cpp ├── 17-Date.cpp ├── 54-encoder-base64.cpp ├── 55-encoder-base16.cpp ├── 56-encoder-binary.cpp ├── 56-encoder-bytes.cpp ├── 21-ReadStreams.cpp ├── 20-File.cpp ├── 44-CryptoRSA.cpp ├── 42-CryptoDH.cpp ├── 23-ZlibFileStream.cpp ├── 13-Generator.cpp ├── 14-WaitEvent.cpp ├── 2-Console.cpp ├── 10-Optional.cpp ├── 11-Expected.cpp ├── 44-CryptoXOR.cpp ├── 22-WriteStreams.cpp ├── 26-Query.cpp ├── 25-Cookie.cpp ├── 41-Crypto.cpp ├── 28-Path.cpp ├── 15-Observer.cpp ├── 19-JsonParse.cpp ├── 43-CryptoDSA.cpp ├── 16-Promises.cpp ├── 17-async_task_resolver.cpp ├── 5-Tuple.cpp ├── 23-std_IO_stream.cpp ├── 10-Regex.cpp ├── 31-HTTP-Server.cpp ├── 33-HTTPS-Server.cpp ├── 8-Env.cpp ├── 16-Asyn_Promises.cpp ├── 40-Cluster.cpp ├── 29-HTTP-Client.cpp ├── 58-atomic.cpp ├── 16-Timer.cpp ├── 3-Conio.cpp ├── 6-String.cpp ├── 11-Task.cpp ├── 30-HTTPS-Client.cpp ├── 8-splice.cpp ├── 14-Event.cpp ├── 45-TCPClient.cpp ├── 46-TCPServer.cpp ├── 47-UDPClient.cpp ├── 48-UDPServer.cpp ├── 35-WS-Client.cpp ├── 50-TLSServer.cpp ├── 49-TLSClient.cpp ├── 0-Terminal_Color.cpp ├── 51-Worker.cpp ├── 12-Coroutine.cpp ├── 37-WSS-Client.cpp ├── 39-LoadBalancing.cpp ├── 36-WS-Server.cpp ├── 9-Regex.cpp ├── 38-WSS-Server.cpp ├── 7-Queue.cpp ├── 4-Garbage-Colector.cpp ├── 5-Array.cpp ├── 57-mutex.cpp ├── 27-URL.cpp ├── 18-Json_Stringify.cpp ├── 39-WS-load-test.cpp ├── 53-encoder-utf.cpp ├── 17-Json.cpp ├── 46-TCP.cpp ├── 48-UDP.cpp ├── 50-TLS.cpp ├── 38-WS.cpp ├── 32-HTTP-Server.cpp ├── 34-HTTPS-Server.cpp ├── 38-WSS.cpp └── 0-Test.cpp ├── main.cpp ├── include └── nodepp │ ├── conio.h │ ├── os.h │ ├── limit.h │ ├── sleep.h │ ├── env.h │ ├── poll.h │ ├── fs.h │ ├── dns.h │ ├── socket.h │ ├── atomic.h │ ├── file.h │ ├── mutex.h │ ├── optional.h │ ├── worker.h │ ├── windows │ ├── limit.h │ ├── sleep.h │ ├── env.h │ └── os.h │ ├── expected.h │ ├── cookie.h │ ├── query.h │ ├── debug.h │ ├── import.h │ ├── posix │ ├── sleep.h │ ├── limit.h │ ├── env.h │ ├── os.h │ └── npoll.h │ ├── ssocket.h │ ├── popen.h │ ├── console.h │ ├── variant.h │ ├── coroutine.h │ ├── except.h │ ├── function.h │ ├── stream.h │ ├── loop.h │ ├── tuple.h │ ├── cluster.h │ ├── signal.h │ ├── observer.h │ ├── any.h │ ├── event.h │ └── ws.h ├── CMakeLists.txt ├── .github ├── FUNDING.yml └── workflows │ └── main.yml ├── LICENSE └── test ├── tuple.cpp ├── optional.cpp ├── expected.cpp ├── function.cpp ├── file.cpp ├── loop.cpp ├── ptr.cpp ├── worker.cpp ├── dns.cpp ├── path.cpp ├── cookie.cpp ├── query.cpp ├── atomic.cpp ├── any.cpp ├── observer.cpp ├── regex.cpp ├── variant.cpp ├── main.cpp ├── task.cpp ├── map.cpp ├── event.cpp └── wait.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | main.exe 2 | main -------------------------------------------------------------------------------- /examples/1-Hello-World.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | console::log("¡Hello World!"); 8 | 9 | } -------------------------------------------------------------------------------- /examples/40-Popen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | auto pid = popen::async( "curl https://www.google.com -Ls" ); 9 | 10 | pid.onData([]( string_t data ){ console::log( data ); }); 11 | pid.onClose([=](){ console::log("done"); }); 12 | 13 | } -------------------------------------------------------------------------------- /examples/56-encoder-hex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | ulong data = 63499; 9 | auto out = encoder::hex::atob( data ); 10 | 11 | console::log( ">>", out ); 12 | console::log( "<<", encoder::hex::btoa(out) ); 13 | 14 | } -------------------------------------------------------------------------------- /examples/17-Date.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | auto time1 = date_t( 2025, 7, 9, false ); 9 | auto time2 = date_t( 2025, 7, 19, false ); 10 | auto time3 = date2 - date1; 11 | 12 | console::log( "days left:", time3.get_day() ); 13 | 14 | } -------------------------------------------------------------------------------- /examples/54-encoder-base64.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | string_t data = "hello world"; 9 | string_t out = encoder::base64::atob( data ); 10 | 11 | console::log( ">>", out ); 12 | console::log( "<<", encoder::base64::btoa( out ) ); 13 | 14 | } -------------------------------------------------------------------------------- /examples/55-encoder-base16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | string_t data = "hello world"; 9 | string_t out = encoder::buffer::atob( data ); 10 | 11 | console::log( ">>", out ); 12 | console::log( "<<", encoder::buffer::btoa( out ) ); 13 | 14 | } -------------------------------------------------------------------------------- /examples/56-encoder-binary.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | ulong data = 63499; 9 | auto out = encoder::bin::atob( data ); 10 | 11 | console::log( ">>", array_t(out).join("") ); 12 | console::log( "<<", encoder::bin::btoa(out) ); 13 | 14 | } -------------------------------------------------------------------------------- /examples/56-encoder-bytes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | ulong data = 63499; 9 | auto out = encoder::bytes::atob( data ); 10 | 11 | console::log( ">>", array_t(out).join() ); 12 | console::log( "<<", encoder::bytes::btoa(out) ); 13 | 14 | } -------------------------------------------------------------------------------- /examples/21-ReadStreams.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto _str = fs::readable( "Path/To/File" ); 10 | 11 | _str.onData.on([]( string_t chunk ){ 12 | console::log( chunk ); 13 | }); 14 | 15 | stream::pipe( _str ); 16 | 17 | } -------------------------------------------------------------------------------- /examples/20-File.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | // Write File 9 | file_t fileA ( "file.txt", "w" ); 10 | fileA.write( "Hello Worl!" ); 11 | 12 | /*-----------------------------------------*/ 13 | 14 | // Read File 15 | file_t fileB ( "file.txt", "r" ); 16 | console::log( fileB.read() ); 17 | 18 | } -------------------------------------------------------------------------------- /examples/44-CryptoRSA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | crypto::encrypt::RSA ppt; 9 | string_t msg = "Hello World!"; 10 | 11 | auto data = ppt.private_encrypt( msg ); 12 | console::log( data.size(), data ); 13 | 14 | auto decp = ppt.public_decrypt( data ); 15 | console::log( decp.size(), decp ); 16 | 17 | } -------------------------------------------------------------------------------- /examples/42-CryptoDH.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | crypto::sign::DH key1, key2, key3; 10 | 11 | auto skey1 = key1.get_public_key(); 12 | auto sign1 = key1.sign( skey1 ); 13 | 14 | console::log( sign1 ); 15 | 16 | console::log( "verified", key1.verify( skey1, sign1 ) ); 17 | 18 | } -------------------------------------------------------------------------------- /examples/23-ZlibFileStream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto write= fs::writable("PATH_1"); // = file_t( "PATH", "w" ) 10 | auto read = fs::readable("PATH_2"); // = file_t( "PATH", "r" ) 11 | 12 | read.onClose.once([](){ console::log("done"); }); 13 | 14 | zlib::gzip::pipe( read, write ); 15 | 16 | } -------------------------------------------------------------------------------- /examples/13-Generator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | GENERATOR( process_1 ) { 6 | 7 | int counter = 10; 8 | 9 | coEmit(){ 10 | coBegin 11 | 12 | while( counter-->0 ){ 13 | console::done( ":>", counter ); 14 | coNext; 15 | } 16 | 17 | coFinish 18 | } 19 | 20 | }; 21 | 22 | void onMain(){ 23 | process_1 A; process::add(A); 24 | } -------------------------------------------------------------------------------- /examples/14-WaitEvent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | wait_t ev; 10 | 11 | ev.on("1",[](){ console::log(" World 1 "); }); 12 | ev.on("2",[](){ console::log(" World 2 "); }); 13 | ev.on("3",[](){ console::log(" World 3 "); }); 14 | 15 | ev.emit( "3" ); 16 | ev.emit( "2" ); 17 | ev.emit( "1" ); 18 | 19 | } -------------------------------------------------------------------------------- /examples/2-Console.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | console::log("this is a simple message"); 8 | 9 | console::info("this is a message info"); 10 | 11 | console::done("this is a done message"); 12 | 13 | console::error("this is an error message"); 14 | 15 | console::success("this is a done message"); 16 | 17 | console::warning("this is a warning message"); 18 | 19 | } -------------------------------------------------------------------------------- /examples/10-Optional.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | optional_t x; 9 | if( x.has_value() ) console::done( x.value() ); 10 | else console::error( "x is empty" ); 11 | 12 | optional_t y ("y has value"); 13 | if( y.has_value() ) console::done( y.value() ); 14 | else console::error( "y is empty" ); 15 | 16 | } -------------------------------------------------------------------------------- /examples/11-Expected.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | expected_t x ( 10 ); 9 | if( x.has_value() ) console::done( x.value() ); 10 | else console::error( x.error() ); 11 | 12 | expected_t y ( "hello" ); 13 | if( y.has_value() ) console::done( y.value() ); 14 | else console::error( y.error() ); 15 | 16 | } -------------------------------------------------------------------------------- /examples/44-CryptoXOR.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | crypto::encrypt::XOR XOR ( "PASSWORD" ); 9 | crypto::encrypt::XOR ROX ( "PASSWORD" ); 10 | string_t msg = "Hello World!"; 11 | 12 | XOR.update( msg ); 13 | auto enc = XOR.get(); 14 | console::log( "->", enc ); 15 | 16 | ROX.update( enc ); 17 | auto dec = ROX.get(); 18 | console::log( "->", dec ); 19 | 20 | } -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | auto ppt = crypto::encrypt::AES_192_CBC( "key1234567890" ); 9 | ppt.update("Hello World!"); 10 | auto p = ppt.get(); 11 | 12 | console::log( ":>", p.size(), p ); 13 | 14 | auto ttp = crypto::decrypt::AES_192_CBC( "key1234567890" ); 15 | ttp.update( p ); 16 | auto q = ttp.get(); 17 | 18 | console::log( ":>", q.size(), q ); 19 | 20 | } -------------------------------------------------------------------------------- /examples/22-WriteStreams.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | file_t read ( "Path/To/File1", "r" ); 10 | file_t write( "Path/To/File2", "w" ); 11 | 12 | read.onData.on([]( string_t chunk ){ 13 | console::log( chunk ); 14 | }); 15 | 16 | read.onClose.on([](){ 17 | console::log("closed"); 18 | }); 19 | 20 | stream::pipe( read, write ); 21 | 22 | } -------------------------------------------------------------------------------- /examples/26-Query.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | auto q = query::parse( "?var1=10&var2=20&var3=30" ); 9 | 10 | for( auto x: q.data() ){ 11 | console::log( x.first, ":", x.second ); 12 | } 13 | 14 | console::log( q["var1"] ); 15 | console::log( q["var2"] ); 16 | console::log( q["var3"] ); 17 | 18 | q["var4"] = "Hello World!"; 19 | 20 | console::log( query::format(q) ); 21 | 22 | } -------------------------------------------------------------------------------- /examples/25-Cookie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | auto q = cookie::parse( "var1=10;var2=20;var3=30" ); 9 | 10 | for( auto x: q.data() ){ 11 | console::log( x.first, ":", x.second ); 12 | } 13 | 14 | console::log( q["var1"] ); 15 | console::log( q["var2"] ); 16 | console::log( q["var3"] ); 17 | 18 | q["var4"] = "Hello World!"; 19 | 20 | console::log( cookie::format(q) ); 21 | 22 | } -------------------------------------------------------------------------------- /examples/41-Crypto.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | auto ppt = crypto::encrypt::AES_192_CBC( "key1234567890" ); 9 | ppt.update("Hello World!"); 10 | auto p = ppt.get(); 11 | 12 | console::log( ":>", p.size(), p ); 13 | 14 | auto ttp = crypto::decrypt::AES_192_CBC( "key1234567890" ); 15 | ttp.update( p ); 16 | auto q = ttp.get(); 17 | 18 | console::log( ":>", q.size(), q ); 19 | 20 | } -------------------------------------------------------------------------------- /examples/28-Path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | string_t dir = path::join( os::cwd(), "www", "index.html" ); 10 | auto ppt = path::parse( dir ); 11 | 12 | console::log( "mime:", path::mimetype(ppt) ); 13 | console::log( "root:", ppt.root ); 14 | console::log( "path:", ppt.path ); 15 | console::log( "name:", ppt.name ); 16 | console::log( "base:", ppt.base ); 17 | console::log( "extn:", ppt.ext ); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /examples/15-Observer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | observer_t obj ({ 8 | { "a", 0 }, 9 | { "b", 0 } 10 | }); 11 | 12 | void onMain(){ 13 | 14 | obj.once( "b", []( any_t A, any_t B ){ 15 | console::done( " B:>", (int)A, "|", (int)B ); 16 | }); 17 | 18 | obj.on( "a", []( any_t A, any_t B ){ 19 | console::error( "A:>", (int)A, "|", (int)B ); 20 | }); 21 | 22 | obj.set( "b", rand() % 10 ); 23 | obj.set( "a", rand() % 10 ); 24 | 25 | } -------------------------------------------------------------------------------- /examples/19-JsonParse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | object_t ppt = json::parse(R"({ 9 | "var1": 10, 10 | "var4": true, 11 | "var3": 10.99, 12 | "var2": "Hello World", 13 | "var6": { "var1": "Nice Work" }, 14 | "var7": [ "Hello", 10, "World" ], 15 | })"); 16 | 17 | console::log( ppt["var3"].as() ); 18 | console::log( ppt["var7"][0].as() ); 19 | console::log( ppt["var6"]["var1"].as() ); 20 | 21 | } -------------------------------------------------------------------------------- /examples/43-CryptoDSA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | crypto::sign::DSA ppt; 10 | string_t msg = "Hello World!"; 11 | auto sign = ppt.sign( msg ); 12 | ptr_t data ( sign.size() ); 13 | 14 | memcpy( &data, sign.get(), data.size() ); 15 | 16 | console::log( "sign:", encoder::hex::get( data ) ); 17 | 18 | console::log( "verf:", ppt.verify( msg, sign ) ); 19 | console::log( "verf:", ppt.verify( msg, "Hello World!" ) ); 20 | 21 | } -------------------------------------------------------------------------------- /examples/16-Promises.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | promise_t([=]( res_t res, rej_t rej ){ 10 | timer::timeout([=](){ res(10); },1000); 11 | }) 12 | 13 | .then([=]( int res ){ 14 | console::log("resolved:>",res); 15 | }) 16 | 17 | .fail([=]( except_t rej ){ 18 | console::log("rejected:>",rej); 19 | }) 20 | 21 | .finally([=](){ 22 | console::log("--finally--"); 23 | }); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /examples/17-async_task_resolver.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | ptr_t value = new uint(0); 9 | 10 | promise::resolve( coroutine::add( COROUTINE(){ 11 | coBegin 12 | 13 | coDelay( 1000 ); 14 | *value = 10; 15 | 16 | coFinish 17 | })) 18 | 19 | .then([=]( null_t ){ 20 | console::log( *value ); 21 | }) 22 | 23 | .fail([=]( except_t err ){ 24 | console::error( err.what() ); 25 | }); 26 | 27 | console::log( "Hello!" ); 28 | 29 | } -------------------------------------------------------------------------------- /examples/5-Tuple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*────────────────────────────────────────────────────────────────────────────*/ 5 | 6 | using namespace nodepp; 7 | 8 | /*────────────────────────────────────────────────────────────────────────────*/ 9 | 10 | void onMain(){ 11 | 12 | tuple_t tp ( 10, 10.50, "hello world!" ); 13 | 14 | console::log( tuple::get<0>(tp) ); 15 | console::log( tuple::get<1>(tp) ); 16 | console::log( tuple::get<2>(tp) ); 17 | 18 | } 19 | 20 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /examples/23-std_IO_stream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain() { 7 | 8 | console::log( "write something asynchronously" ); 9 | 10 | auto output = fs::std_output(); // writable file stream 11 | auto input = fs::std_input(); // readable file stream 12 | auto error = fs::std_error(); // writable file stream 13 | 14 | input.onData([=]( string_t data ){ 15 | output.write( "your input is: " ); 16 | output.write( data ); 17 | output.write( "\n" ); 18 | }); 19 | 20 | stream::pipe( input ); 21 | 22 | } -------------------------------------------------------------------------------- /examples/10-Regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | string_t message = R"( 9 | ![Imagen1](URL1) 10 | ![Imagen2](URL2) 11 | ![Imagen3](URL3) 12 | ![Imagen4](URL5) 13 | )"; 14 | 15 | regex_t reg ("!\\[([^\\]]+)\\]\\(([^\\)]+)\\)"); 16 | 17 | console::log( "-- --" ); 18 | for( auto &x: reg.match_all( message ) ){ 19 | console::log( "->", x ); 20 | } 21 | 22 | console::log( "-- --" ); 23 | for( auto &x: reg.get_memory() ){ 24 | console::log( "->", x ); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /examples/31-HTTP-Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto server = http::server([=]( http_t cli ){ 10 | 11 | console::log( cli.path, cli.get_fd() ); 12 | 13 | cli.write_header( 200, header_t({ 14 | { "content-type", "text/html" } 15 | })); 16 | 17 | cli.write( date::fulltime() ); 18 | 19 | }); 20 | 21 | server.listen( "localhost", 8000, [=]( socket_t server ){ 22 | console::log("server started at http://localhost:8000"); 23 | }); 24 | 25 | } -------------------------------------------------------------------------------- /examples/33-HTTPS-Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | ssl_t ssl; // ( "./ssl/cert.key", "./ssl/cert.crt" ); 10 | 11 | auto server = https::server([=]( https_t cli ){ 12 | 13 | console::log( cli.path, cli.get_fd() ); 14 | 15 | cli.write_header( 200, header_t({ 16 | { "content-type", "text/html" } 17 | })); 18 | 19 | cli.write( date::fulltime() ); 20 | 21 | }, &ssl ); 22 | 23 | server.listen( "localhost", 8000, [=]( ssocket_t server ){ 24 | console::log("server started at https://localhost:8000"); 25 | }); 26 | 27 | } -------------------------------------------------------------------------------- /examples/8-Env.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | // Load Environment Variables using a .env file 8 | process::env::init(".env"); 9 | console::log( process::env::get("VARA") ); 10 | console::log( process::env::get("VARB") ); 11 | 12 | // Add Environment Variables 13 | process::env::set( "mode", "hello" ); 14 | console::log( process::env::get("mode") ); 15 | 16 | // Delete Environment Variables 17 | process::env::remove( "mode" ); 18 | console::log( process::env::get("mode") ); 19 | 20 | // Add Variables using command line 21 | /* g++ -o main main.cpp ; ./main ?NAME_1=VALUE ?NAME_2=VALUE */ 22 | /* eg: ./main ?mode=client */ 23 | 24 | } -------------------------------------------------------------------------------- /examples/16-Asyn_Promises.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | promise_t prom ([=]( res_t res, rej_t rej ){ 10 | timer::timeout([=](){ res(10); },1000); 11 | }); prom.emit(); 12 | 13 | process::add( coroutine::add( COROUTINE(){ 14 | coBegin 15 | 16 | coWait( prom.is_pending() ); 17 | 18 | if( !prom.has_value() ){ coEnd; } 19 | 20 | if( prom.is_resolved() ){ console::done ( prom.get_value().value() ); } 21 | else /*--------------*/ { console::error( prom.get_value().error() ); } 22 | 23 | coFinish 24 | })); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /examples/40-Cluster.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain() { 8 | 9 | if( process::is_parent() ){ 10 | auto pid = cluster::add(); 11 | 12 | pid.onDrain([=](){ console::log("Done"); }); 13 | pid.onData([=]( string_t data ){ 14 | console::log("->",data); 15 | }); 16 | 17 | } else { 18 | process::add( coroutine::add( COROUTINE(){ 19 | static uint x = 10; 20 | coBegin 21 | while( x-->0 ){ 22 | console::log("Hello World!"); 23 | coDelay(1000); 24 | } 25 | coFinish 26 | })); 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /examples/29-HTTP-Client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | fetch_t args; 9 | args.method = "GET"; 10 | args.url = "http://www.google.com/"; 11 | args.headers = header_t({ 12 | { "Host", url::host(args.url) } 13 | }); 14 | 15 | // args.file = file_t("PATH","r"); 16 | // args.body = "MYBODY"; 17 | 18 | http::fetch( args ) 19 | 20 | .then([]( http_t cli ){ 21 | console::log( cli.headers["Host"] ); 22 | cli.onData([]( string_t chunk ){ 23 | console::log( chunk ); 24 | }); stream::pipe( cli ); 25 | }) 26 | 27 | .fail([]( except_t err ){ 28 | console::error( err ); 29 | }); 30 | 31 | } -------------------------------------------------------------------------------- /examples/58-atomic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace nodepp; 7 | 8 | atomic_t shared_variable = 100; 9 | 10 | GENERATOR( my_coroutine ){ 11 | 12 | coEmit(){ 13 | coBegin 14 | while( shared_variable > 0 ){ 15 | console::log( "task>> Hello World", shared_variable.get() ); 16 | --shared_variable; coDelay(100); 17 | } 18 | coFinish 19 | } 20 | 21 | }; 22 | 23 | void onMain(){ 24 | 25 | // Launching a worker to run the coroutine 26 | worker::add(my_coroutine()); 27 | // Launching another worker 28 | worker::add(my_coroutine()); 29 | // Adding the coroutine to the main event loop as well 30 | process::add(my_coroutine()); 31 | 32 | } -------------------------------------------------------------------------------- /examples/16-Timer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | // add: a Coroutine Based Timer 9 | auto C = timer::add( coroutine::add( COROUTINE(){ 10 | static uchar x = 100; 11 | coBegin 12 | 13 | while( x-->0 ){ 14 | console::log(" timer task "); 15 | coNext; 16 | } 17 | 18 | coFinish 19 | }) ,1000); 20 | 21 | // Interval: a setInterval equivalent 22 | auto A = timer::interval([=](){ 23 | console::done("set interval"); 24 | },1000); 25 | 26 | // Timeout: a setTimeout equivalent 27 | auto B = timer::timeout([=](){ 28 | console::error("set timeout"); 29 | },1000); 30 | 31 | // Turn off an specific timer 32 | // timer::clear(A); 33 | 34 | } -------------------------------------------------------------------------------- /examples/3-Conio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | conio::foreground( C_GREEN | C_BOLD ); 8 | conio::log(" Hello World! \n"); 9 | 10 | conio::foreground( C_RED | C_BOLD ); 11 | conio::log(" Hello World! \n"); 12 | 13 | conio::foreground( C_YELLOW | C_BOLD ); 14 | conio::log(" Hello World! \n"); 15 | 16 | conio::foreground( C_CYAN | C_BOLD ); 17 | conio::log(" Hello World! \n"); 18 | 19 | conio::foreground( C_MAGENTA | C_BOLD ); 20 | conio::log(" Hello World! \n"); 21 | 22 | conio::foreground( C_WHITE | C_BOLD ); 23 | conio::log(" Hello World! \n"); 24 | 25 | conio::foreground( C_BLACK | C_BOLD ); 26 | conio::background( C_WHITE ); 27 | conio::log(" Hello World! \n"); 28 | 29 | conio::log(" Hello World! \n"); 30 | 31 | } -------------------------------------------------------------------------------- /examples/6-String.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | string_t str = "adcbz"; str += "jpog"; 8 | console::log( str ); 9 | 10 | console::log( "-- --" ); 11 | str = str.sort([]( char a, char b ){ return b > a; }); 12 | console::log( str ); 13 | 14 | console::log( "-- --" ); 15 | console::log( str.slice( 1, 3 ) ); 16 | 17 | console::log( "-- --" ); 18 | console::log( str.splice( 1, 3, "abc" ) ); 19 | 20 | console::log( "-- --" ); 21 | console::log( str ); 22 | 23 | console::log( "-- --" ); 24 | 25 | console::log( "is_empty:", str.empty() ? "true" : "false" ); 26 | console::log( "size:", str.size() ); 27 | console::log( "addr:", str.data() ); str.clear(); 28 | console::log( "is_empty:", str.empty() ? "true" : "false" ); 29 | 30 | } -------------------------------------------------------------------------------- /examples/11-Task.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /*────────────────────────────────────────────────────────────────────────────*/ 4 | 5 | using namespace nodepp; 6 | 7 | /*────────────────────────────────────────────────────────────────────────────*/ 8 | 9 | void onMain(){ 10 | 11 | //return 1 -> will repeat the task 12 | process::add([=](){ 13 | console::done("repeat mode"); 14 | return 1; 15 | }); 16 | 17 | //return -1 -> will kill the task 18 | process::add([=](){ 19 | console::error("once mode"); 20 | return -1; 21 | }); 22 | 23 | //return 0 -> will block until != 0 24 | process::add([=](){ 25 | console::error("block mode"); 26 | return 0; 27 | }); 28 | 29 | } 30 | 31 | /*────────────────────────────────────────────────────────────────────────────*/ 32 | -------------------------------------------------------------------------------- /include/nodepp/conio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_CONIO 13 | #define NODEPP_CONIO 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "windows/conio.h" 19 | #else 20 | #include "posix/conio.h" 21 | #endif 22 | 23 | /*────────────────────────────────────────────────────────────────────────────*/ 24 | 25 | #endif -------------------------------------------------------------------------------- /examples/30-HTTPS-Client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | ssl_t ssl; // ( "./ssl/cert.key", "./ssl/cert.crt" ); 9 | 10 | fetch_t args; 11 | args.method = "GET"; 12 | args.url = "https://www.google.com/"; 13 | args.headers = header_t({ 14 | { "Host", url::host(args.url) } 15 | }); 16 | 17 | // args.file = file_t("PATH","r"); 18 | // args.body = "MYBODY"; 19 | 20 | https::fetch( args, &ssl ) 21 | 22 | .then([]( https_t cli ){ 23 | cli.onData([]( string_t chunk ){ 24 | console::log( chunk.size(), ":>", chunk ); 25 | }); stream::pipe( cli ); 26 | }) 27 | 28 | .fail([]( except_t err ){ 29 | console::error( err ); 30 | }); 31 | 32 | } -------------------------------------------------------------------------------- /examples/8-splice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | array_t arr ({ 0, 1, 2, 3, 4, 5 }); 8 | queue_t que ({ 0, 1, 2, 3, 4, 5 }); 9 | string_t str = "012345"; 10 | 11 | console::log( "str:", str.slice(0,2) ); 12 | console::log( "arr:", arr.slice(0,2).join() ); 13 | console::log( "que:", array_t(que.slice(0,2).data()).join() ); 14 | 15 | console::log( "---" ); 16 | 17 | console::log( "str:", str.splice(2,2,"98") ); 18 | console::log( "arr:", arr.splice(2,2,{9,8}).join() ); 19 | console::log( "que:", array_t(que.splice(2,2,{9,8}).data()).join() ); 20 | 21 | console::log( "---" ); 22 | 23 | console::log( "str:", str ); 24 | console::log( "arr:", arr.join() ); 25 | console::log( "que:", array_t(que.data()).join() ); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /examples/14-Event.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | event_t<> ev; // Event is task safety thanks to GC 10 | 11 | // create an event that can be emitted many times 12 | ev.on([](){ console::done(" World 1 "); }); 13 | 14 | // create an event that can be emitted once 15 | ev.on([](){ console::done(" hello "); }); 16 | 17 | // Emit Events 18 | ev.emit(); 19 | console::log( "->", ev.size() ); 20 | 21 | // Clear Even Queue 22 | ev.clear(); 23 | 24 | // turn of an specific event 25 | auto item = ev.on([](){ 26 | console::log("me cago en la puta"); 27 | }); 28 | console::log( "->", ev.size() ); 29 | 30 | ev.off( item ); ev.emit(); 31 | console::log( "->", ev.size() ); 32 | 33 | } -------------------------------------------------------------------------------- /examples/45-TCPClient.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto client = tcp::client(); 10 | 11 | client.onOpen([=]( socket_t cli ){ 12 | 13 | console::log("connected", cli.get_peername() ); 14 | auto cin = fs::std_input(); 15 | 16 | cli.onData([=]( string_t data ){ 17 | console::log( data ); 18 | }); 19 | 20 | cin.onData([=]( string_t data ){ 21 | cli.write( data ); 22 | }); 23 | 24 | cli.onClose.once([=](){ 25 | console::log("closed"); 26 | cin.close(); 27 | }); 28 | 29 | stream::pipe( cli ); 30 | stream::pipe( cin ); 31 | 32 | }); 33 | 34 | client.connect( "localhost", 8000, []( socket_t cli ){ 35 | console::log("-> tcp://localhost:8000"); 36 | }); 37 | 38 | } -------------------------------------------------------------------------------- /include/nodepp/os.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_OSS 13 | #define NODEPP_OSS 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "windows/os.h" 19 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 20 | #include "posix/os.h" 21 | #else 22 | #error "This OS Does not support os.h" 23 | #endif 24 | 25 | /*────────────────────────────────────────────────────────────────────────────*/ 26 | 27 | #endif -------------------------------------------------------------------------------- /examples/46-TCPServer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto server = tcp::server(); 10 | 11 | server.onConnect([=]( socket_t cli ){ 12 | 13 | console::log("connected", cli.get_peername() ); 14 | auto cin = fs::std_input(); 15 | 16 | cli.onData([=]( string_t data ){ 17 | console::log( data ); 18 | }); 19 | 20 | cin.onData([=]( string_t data ){ 21 | cli.write( data ); 22 | }); 23 | 24 | cli.onDrain.once([=](){ 25 | console::log("closed"); 26 | cin.close(); 27 | }); 28 | 29 | stream::pipe( cli ); 30 | stream::pipe( cin ); 31 | 32 | }); 33 | 34 | server.listen( "localhost", 8000, []( socket_t srv ){ 35 | console::log("-> tcp://localhost:8000"); 36 | }); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /examples/47-UDPClient.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto client = udp::client(); 10 | 11 | client.onConnect([=]( socket_t cli ){ 12 | 13 | console::log("connected", cli.get_peername() ); 14 | auto cin = fs::std_input(); 15 | 16 | cli.onData([=]( string_t data ){ 17 | console::log( data ); 18 | }); 19 | 20 | cin.onData([=]( string_t data ){ 21 | cli.write( data ); 22 | }); 23 | 24 | cli.onDrain.once([=](){ 25 | console::log("closed"); 26 | cin.close(); 27 | }); 28 | 29 | stream::pipe( cli ); 30 | stream::pipe( cin ); 31 | 32 | }); 33 | 34 | client.connect( "localhost", 8000, []( socket_t cli ){ 35 | console::log("-> udp://localhost:8000"); 36 | }); 37 | 38 | } -------------------------------------------------------------------------------- /examples/48-UDPServer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto server = udp::server(); 10 | 11 | server.onConnect([=]( socket_t cli ){ 12 | 13 | console::log("connected", cli.get_peername() ); 14 | auto cin = fs::std_input(); 15 | 16 | cli.onData([=]( string_t data ){ 17 | console::log( data ); 18 | }); 19 | 20 | cin.onData([=]( string_t data ){ 21 | cli.write( data ); 22 | }); 23 | 24 | cli.onDrain.once([=](){ 25 | console::log("closed"); 26 | cin.close(); 27 | }); 28 | 29 | stream::pipe( cli ); 30 | stream::pipe( cin ); 31 | 32 | }); 33 | 34 | server.listen( "localhost", 8000, []( socket_t srv ){ 35 | console::log("-> udp://localhost:8000"); 36 | }); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /examples/35-WS-Client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace nodepp; 7 | 8 | void onMain() { 9 | 10 | auto client = ws::client( "ws://localhost:8000/" ); 11 | auto cin = fs::std_input(); 12 | 13 | client.onConnect([=]( ws_t cli ){ 14 | 15 | console::log("connected", cli.get_peername() ); 16 | 17 | cli.onData([]( string_t chunk ){ 18 | console::log("client:>",chunk); 19 | }); 20 | 21 | cin.onData([=]( string_t data ){ 22 | cli.write( data ); 23 | }); 24 | 25 | cli.onDrain([=](){ 26 | console::log("closed"); 27 | cin.close(); 28 | }); 29 | 30 | stream::pipe( cin ); 31 | 32 | }); 33 | 34 | client.onError([=]( except_t err ){ 35 | console::log( "<>", err.data() ); 36 | }); 37 | 38 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | project(nodepp VERSION 1.3.0) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 6 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 7 | set(NODEPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") 8 | 9 | # Search for ZLIB 10 | find_package(ZLIB REQUIRED) 11 | if(NOT ZLIB_FOUND) 12 | message(FATAL_ERROR "ZLIB not found. Please install libz-dev or equivalent files.") 13 | endif() 14 | 15 | # Search for OpenSSL 16 | find_package(OpenSSL REQUIRED COMPONENTS Crypto SSL) 17 | if(NOT OpenSSL_FOUND) 18 | message(FATAL_ERROR "OpenSSL not found. Please install libopenssl-dev or equivalent files.") 19 | endif() 20 | 21 | # interface-target 22 | add_library(nodepp INTERFACE) 23 | target_include_directories(nodepp INTERFACE ${NODEPP_INCLUDE_DIR}) 24 | target_link_libraries(nodepp INTERFACE -lssl -lcrypto -lz $<$,$>:ws2_32> ) -------------------------------------------------------------------------------- /examples/50-TLSServer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto ssl = ssl_t(); 10 | auto server = tls::server( &ssl ); 11 | 12 | server.onConnect([=]( ssocket_t cli ){ 13 | 14 | console::log("connected" ); 15 | auto cin = fs::std_input(); 16 | 17 | cli.onData([=]( string_t data ){ 18 | console::log( data ); 19 | }); 20 | 21 | cin.onData([=]( string_t data ){ 22 | cli.write( data ); 23 | }); 24 | 25 | cli.onDrain.once([=](){ 26 | console::log("closed"); 27 | cin.close(); 28 | }); 29 | 30 | stream::pipe( cli ); 31 | stream::pipe( cin ); 32 | 33 | }); 34 | 35 | server.listen( "localhost", 8000, []( ssocket_t ){ 36 | console::log("-> tls://localhost:8000"); 37 | }); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /include/nodepp/limit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_LIMIT 13 | #define NODEPP_LIMIT 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "windows/limit.h" 19 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 20 | #include "posix/limit.h" 21 | #else 22 | #error "This OS Does not support limit.h" 23 | #endif 24 | 25 | /*────────────────────────────────────────────────────────────────────────────*/ 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/nodepp/sleep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_SLEEP 13 | #define NODEPP_SLEEP 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "windows/sleep.h" 19 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 20 | #include "posix/sleep.h" 21 | #else 22 | #error "This OS Does not support sleep.h" 23 | #endif 24 | 25 | /*────────────────────────────────────────────────────────────────────────────*/ 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /examples/49-TLSClient.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | auto ssl = ssl_t(); 10 | auto server = tls::client( &ssl ); 11 | 12 | client.onConnect([=]( ssocket_t cli ){ 13 | 14 | console::log("connected" ); 15 | auto cin = fs::std_input(); 16 | 17 | cli.onData([=]( string_t data ){ 18 | console::log( data ); 19 | }); 20 | 21 | cin.onData([=]( string_t data ){ 22 | cli.write( data ); 23 | }); 24 | 25 | cli.onDrain.once([=](){ 26 | console::log("closed"); 27 | cin.close(); 28 | }); 29 | 30 | stream::pipe( cli ); 31 | stream::pipe( cin ); 32 | 33 | }); 34 | 35 | client.connect( "localhost", 8000, []( socket_t cli ){ 36 | console::log("-> tls://localhost:8000"); 37 | }); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /examples/0-Terminal_Color.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain() { 6 | 7 | conio::background( conio::color::cyan | conio::color::bold ); 8 | console::log( "hello world!" ); 9 | conio::reset(); 10 | 11 | conio::foreground( conio::color::red | conio::color::bold ); 12 | console::log( "hello world!" ); 13 | conio::reset(); 14 | 15 | conio::background( conio::color::magenta | conio::color::bold ); 16 | console::log( "hello world!" ); 17 | conio::reset(); 18 | 19 | conio::foreground( conio::color::blue | conio::color::bold ); 20 | console::log( "hello world!" ); 21 | conio::reset(); 22 | 23 | conio::background( conio::color::yellow | conio::color::bold ); 24 | console::log( "hello world!" ); 25 | conio::reset(); 26 | 27 | conio::foreground( conio::color::green | conio::color::bold ); 28 | console::log( "hello world!" ); 29 | conio::reset(); 30 | 31 | } -------------------------------------------------------------------------------- /include/nodepp/env.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_ENV 13 | #define NODEPP_ENV 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "file.h" 19 | #include "windows/env.h" 20 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 21 | #include "file.h" 22 | #include "posix/env.h" 23 | #else 24 | #error "This OS Does not support env.h" 25 | #endif 26 | 27 | /*────────────────────────────────────────────────────────────────────────────*/ 28 | 29 | #endif -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: edbc_repo # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /examples/51-Worker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | ptr_t x = new int(100); mutex_t mut; 10 | 11 | worker::add( mutex::add( mut, coroutine::add( COROUTINE(){ 12 | coBegin 13 | 14 | while( *x > 0 ){ 15 | console::log( "wrk2>> Hello World", *x ); 16 | *x-=1; coDelay(100); } 17 | 18 | coFinish 19 | }) )); 20 | 21 | worker::add( mutex::add( mut, coroutine::add( COROUTINE(){ 22 | coBegin 23 | 24 | while( *x > 0 ){ 25 | console::log( "wrk1>> Hello World", *x ); 26 | *x-=1; coDelay(100); } 27 | 28 | coFinish 29 | }) )); 30 | 31 | worker::add( mutex::add( mut, coroutine::add( COROUTINE(){ 32 | coBegin 33 | 34 | while( *x > 0 ){ 35 | console::log( "wrk0>> Hello World", *x ); 36 | *x-=1; coDelay(100); } 37 | 38 | coFinish 39 | }) )); 40 | 41 | } -------------------------------------------------------------------------------- /examples/12-Coroutine.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*────────────────────────────────────────────────────────────────────────────*/ 5 | 6 | using namespace nodepp; 7 | 8 | /*────────────────────────────────────────────────────────────────────────────*/ 9 | 10 | void onMain(){ 11 | 12 | auto file = fs::readable( "LICENSE" ); 13 | auto x = type::bind( file ); 14 | 15 | process::add( coroutine::add( COROUTINE(){ 16 | coBegin 17 | 18 | while( x->is_available() ){ 19 | console::log( ":>", x->read_line().slice(0,-1) ); 20 | coNext; 21 | } 22 | 23 | coFinish 24 | })); 25 | 26 | process::add( coroutine::add( COROUTINE(){ 27 | coBegin 28 | 29 | while( x->is_available() ){ 30 | console::done("Hello World"); 31 | coNext; 32 | } 33 | 34 | coFinish 35 | })); 36 | 37 | } 38 | 39 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /examples/37-WSS-Client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace nodepp; 7 | 8 | void onMain() { 9 | 10 | ssl_t ssl; //ssl_t ssl( "./ssl/cert.key", "./ssl/cert.crt" ); 11 | 12 | auto client = wss::client( "wss://localhost:8000/", &ssl ); 13 | auto cin = fs::std_input(); 14 | 15 | client.onConnect([=]( wss_t cli ){ 16 | 17 | console::log("connected"); 18 | 19 | cli.onData([]( string_t chunk ){ 20 | console::log("client:>",chunk); 21 | }); 22 | 23 | cin.onData([=]( string_t data ){ 24 | cli.write( data ); 25 | }); 26 | 27 | cli.onDrain([=](){ 28 | console::log("closed"); 29 | cin.close(); 30 | }); 31 | 32 | stream::pipe( cin ); 33 | 34 | }); 35 | 36 | client.onError([=]( except_t err ){ 37 | console::log( "<>", err.data() ); 38 | }); 39 | 40 | } -------------------------------------------------------------------------------- /include/nodepp/poll.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_POLL 13 | #define NODEPP_POLL 14 | 15 | #include "limit.h" 16 | #include "wait.h" 17 | 18 | #if _POLL_ == NODEPP_POLL_WPOLL 19 | #include "posix/npoll.h" 20 | #elif _POLL_ == NODEPP_POLL_EPOLL 21 | #include "posix/epoll.h" 22 | #elif _POLL_ == NODEPP_POLL_KPOLL 23 | #include "posix/kpoll.h" 24 | #elif _POLL_ == NODEPP_POLL_POLL 25 | #include "posix/npoll.h" 26 | #else 27 | #include "posix/npoll.h" 28 | #endif 29 | 30 | #endif 31 | 32 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /examples/39-LoadBalancing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace nodepp; 11 | 12 | void server( int process ){ 13 | 14 | auto server = http::server([=]( http_t cli ){ 15 | 16 | cli.write_header( 200, header_t({ 17 | { "Content-Type", "text/html" } 18 | }) ); 19 | 20 | cli.write("Hello World! \n"); 21 | cli.write("Load Balanced Server"); 22 | 23 | }); 24 | 25 | server.listen( "localhost", 8000, [=]( socket_t server ){ 26 | console::log("-> http://localhost:8000"); 27 | }); 28 | 29 | } 30 | 31 | void onMain(){ 32 | 33 | if ( process::is_child() ){ server( os::pid() ); } else { 34 | for( auto x = os::cpus(); x--; ){ 35 | cluster::add().onData([=]( string_t data ){ 36 | conio::log( data ); 37 | }); 38 | }} 39 | 40 | } -------------------------------------------------------------------------------- /examples/36-WS-Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace nodepp; 10 | 11 | void onMain(){ 12 | 13 | auto server = http::server([=]( http_t cli ){ 14 | 15 | cli.write_header( 200, header_t({ 16 | { "Content-Security-Policy", "*" } 17 | }) ); 18 | 19 | cli.write("Hello World!"); 20 | 21 | }); ws::server( server ); 22 | 23 | server.onConnect([=]( ws_t cli ){ 24 | 25 | console::log("connected", cli.get_peername() ); 26 | 27 | cli.onData([=]( string_t data ){ 28 | console::log( data ); 29 | }); 30 | 31 | cli.onDrain([=](){ 32 | console::log("closed"); 33 | }); 34 | 35 | }); 36 | 37 | server.listen( "localhost", 8000, [=]( socket_t server ){ 38 | console::log("server started at http://localhost:8000"); 39 | }); 40 | 41 | } -------------------------------------------------------------------------------- /include/nodepp/fs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_FS 13 | #define NODEPP_FS 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "path.h" 19 | #include "stream.h" 20 | #include "windows/fs.h" 21 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 22 | #include "path.h" 23 | #include "stream.h" 24 | #include "posix/fs.h" 25 | #else 26 | #error "This OS Does not support fs.h" 27 | #endif 28 | 29 | /*────────────────────────────────────────────────────────────────────────────*/ 30 | 31 | #endif -------------------------------------------------------------------------------- /include/nodepp/dns.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_DNS 13 | #define NODEPP_DNS 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "url.h" 19 | #include "socket.h" 20 | #include "windows/dns.h" 21 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 22 | #include "url.h" 23 | #include "socket.h" 24 | #include "posix/dns.h" 25 | #else 26 | #error "This OS Does not support dns.h" 27 | #endif 28 | 29 | /*────────────────────────────────────────────────────────────────────────────*/ 30 | 31 | #endif -------------------------------------------------------------------------------- /examples/9-Regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | string_t message = "Hello 123 Dude"; 9 | 10 | console::log( "-> \\d+", regex::test( message, "\\d+" ) ? "true" : "false" ); 11 | 12 | console::log( "-> 123", regex::test( message, "123" ) ? "true" : "false" ); 13 | 14 | console::log( "-> aaa", regex::test( message, "aaa" ) ? "true" : "false" ); 15 | 16 | console::log( "-- --" ); 17 | 18 | console::log( "->", regex::match( message, "[0-9]+" ) ); 19 | 20 | console::log( "->", regex::split( message, "\\s+" ).join(" | ") ); 21 | 22 | console::log( "->", regex::match_all( message, "[0-9a-z]+", true ).join(" | ") ); 23 | 24 | console::log( "->", regex::replace( message, "\\d+", "world" ) ); 25 | 26 | console::log( "->", regex::replace_all( message, "[0-9a-z]+", "nodepp", true ) ); 27 | 28 | console::log( "-- --" ); 29 | 30 | for( auto &x: regex::split( message, "\\s+" ) ){ 31 | console::log( "-->", x ); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /examples/38-WSS-Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace nodepp; 10 | 11 | void onMain(){ 12 | 13 | ssl_t ssl; //ssl_t ssl( "./ssl/cert.key", "./ssl/cert.crt" ); 14 | 15 | auto server = https::server([=]( https_t cli ){ 16 | 17 | cli.write_header( 200, header_t({ 18 | { "Content-Security-Policy", "*" } 19 | }) ); 20 | 21 | cli.write("Hello World!"); 22 | 23 | }, &ssl ); wss::server( server ); 24 | 25 | server.onConnect([=]( wss_t cli ){ 26 | 27 | console::log("connected"); 28 | 29 | cli.onData([=]( string_t data ){ 30 | console::log( data ); 31 | }); 32 | 33 | cli.onDrain([=](){ 34 | console::log("closed"); 35 | }); 36 | 37 | }); 38 | 39 | server.listen( "localhost", 8000, [=]( ssocket_t server ){ 40 | console::log("server started at https://localhost:8000"); 41 | }); 42 | 43 | } -------------------------------------------------------------------------------- /include/nodepp/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_SOCKET 13 | #define NODEPP_SOCKET 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "os.h" 19 | #include "limit.h" 20 | #include "stream.h" 21 | #include "windows/socket.h" 22 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 23 | #include "os.h" 24 | #include "limit.h" 25 | #include "stream.h" 26 | #include "posix/socket.h" 27 | #else 28 | #error "This OS Does not support socket.h" 29 | #endif 30 | 31 | /*────────────────────────────────────────────────────────────────────────────*/ 32 | 33 | #endif -------------------------------------------------------------------------------- /examples/7-Queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | queue_t que ({ 10, 20, 30 }); 8 | que.push( 40 ); 9 | que.push( 50 ); 10 | que.unshift( 60 ); 11 | que.unshift( 70 ); 12 | que.insert( 2, 80 ); 13 | 14 | auto item = que.first(); 15 | while( item != nullptr ){ 16 | console::log( "->", item->data ); 17 | item = item->next; 18 | } 19 | 20 | console::log("-- --"); 21 | for( auto &x: que.data() ){ console::log( "->", x ); } 22 | 23 | console::log("-- --"); 24 | que.map([]( uint item ){ console::log( "->", item ); }); 25 | 26 | console::log("-- --"); 27 | 28 | que.sort([=]( uint a, uint b ){ 29 | return a <= b; 30 | }) .map([]( uint item ){ 31 | console::log( "->", item ); 32 | }); 33 | 34 | console::log("-- --"); 35 | 36 | console::log( "is_empty:", que.empty() ? "true" : "false" ); 37 | console::log( "size:", que.size() ); 38 | console::log( "addr:", que.data() ); que.clear(); 39 | console::log( "is_empty:", que.empty() ? "true" : "false" ); 40 | 41 | } -------------------------------------------------------------------------------- /examples/4-Garbage-Colector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | ptr_t GC = new uint(10); 8 | 9 | console::log("-- --"); 10 | console::log( "value->", *GC ); 11 | console::log( "addr ->", GC ); 12 | console::log( "count->", GC.count() ); 13 | 14 | process::add([=](){ // <- note = and not & | this is important to correctly share the memory across tasks 15 | 16 | console::log("-- --"); 17 | console::log( "value->", *GC ); 18 | console::log( "addr ->", GC ); 19 | console::log( "count->", GC.count() ); 20 | 21 | return -1; 22 | }); 23 | 24 | process::await([&](){ // <- note & instead = | but you are still able to use = 25 | 26 | console::log("-- --"); 27 | console::log( "value->", *GC ); 28 | console::log( "addr ->", GC ); 29 | console::log( "count->", GC.count() ); 30 | 31 | return -1; 32 | }); 33 | 34 | console::log("-- --"); 35 | console::log( "value->", *GC ); 36 | console::log( "addr ->", GC ); 37 | console::log( "count->", GC.count() ); 38 | 39 | } -------------------------------------------------------------------------------- /examples/5-Array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace nodepp; 4 | 5 | void onMain(){ 6 | 7 | array_t arr ({ 10, 50, 90, 20 }); 8 | arr.unshift( 30 ); arr.push( 70 ); 9 | arr.insert( 2, 100 ); 10 | 11 | console::log( arr.join(" ") ); 12 | 13 | console::log( "-- --" ); 14 | arr = arr.sort([]( uint a, uint b ){ return a<=b; }); 15 | console::log( arr.join(" ") ); 16 | 17 | console::log( "-- --" ); 18 | console::log( arr.slice( 0, 2 ).join(" ") ); 19 | 20 | console::log( "-- --" ); 21 | console::log( arr.slice( 3 ).join(" ") ); 22 | 23 | console::log( "-- --" ); 24 | console::log( arr.slice( -3 ).join(" ") ); 25 | 26 | console::log( "-- --" ); 27 | console::log( arr.splice( 1, 3, { 1, 2, 3 } ).join(" ") ); 28 | 29 | console::log( "-- --" ); 30 | console::log( arr.join(" ") ); 31 | 32 | console::log( "-- --" ); 33 | 34 | console::log( "is_empty:", arr.empty() ? "true" : "false" ); 35 | console::log( "size:", arr.size() ); 36 | console::log( "addr:", arr.data() ); arr.clear(); 37 | console::log( "is_empty:", arr.empty() ? "true" : "false" ); 38 | 39 | } -------------------------------------------------------------------------------- /include/nodepp/atomic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_ATOMIC 13 | #define NODEPP_ATOMIC 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "windows/atomic.h" 19 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 20 | #include "posix/atomic.h" 21 | #else 22 | #error "This OS Does not support atomic.h" 23 | #endif 24 | 25 | /*────────────────────────────────────────────────────────────────────────────*/ 26 | 27 | namespace nodepp { 28 | atomic_t _EXIT_( false ); 29 | atomic_t _TASK_( int(0) ); 30 | } 31 | 32 | /*────────────────────────────────────────────────────────────────────────────*/ 33 | 34 | #endif -------------------------------------------------------------------------------- /include/nodepp/file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_FILE 13 | #define NODEPP_FILE 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "os.h" 19 | #include "limit.h" 20 | #include "event.h" 21 | #include "generator.h" 22 | #include "windows/file.h" 23 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 24 | #include "os.h" 25 | #include "limit.h" 26 | #include "event.h" 27 | #include "generator.h" 28 | #include "posix/file.h" 29 | #else 30 | #error "This OS Does not support file.h" 31 | #endif 32 | 33 | /*────────────────────────────────────────────────────────────────────────────*/ 34 | 35 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 The Nodepp Project Authors. All Rights Reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /examples/57-mutex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void onMain(){ 8 | 9 | mutex_t mut; 10 | 11 | worker::add( coroutine::add([=](){ 12 | coBegin 13 | 14 | while( true ){ mut.lock([=](){ 15 | // executed in critical section method A 16 | }); coNext; } 17 | 18 | coFinish 19 | })); 20 | 21 | worker::add( coroutine::add([=](){ 22 | coBegin 23 | 24 | while( true ){ coWait( mut._lock([=](){ 25 | // executed in critical section method B 26 | })==-2 ); 27 | // executed out critical section 28 | coNext; } 29 | 30 | coFinish 31 | })); 32 | 33 | worker::add( coroutine::add([=](){ 34 | coBegin 35 | 36 | while( true ){ mut.lock(); 37 | // executed in critical section method C 38 | mut.unlock(); coNext; } 39 | 40 | coFinish 41 | })); 42 | 43 | worker::add( mutex::add( mut, coroutine::add([=](){ 44 | coBegin 45 | 46 | while( true ){ 47 | // executed in critical section method D 48 | coNext; } 49 | 50 | coFinish 51 | }) )); 52 | 53 | } -------------------------------------------------------------------------------- /examples/27-URL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*────────────────────────────────────────────────────────────────────────────*/ 5 | 6 | using namespace nodepp; 7 | 8 | /*────────────────────────────────────────────────────────────────────────────*/ 9 | 10 | void onMain(){ 11 | 12 | string_t uri = "http://becerra:enmanuel@www.google.com/path/to/file#done?var1=10&var2=50&var3=100&var4=hello_world!"; 13 | auto ppt = url::parse( uri ); 14 | 15 | console::log( "hostname:", ppt.hostname ); 16 | console::log( "protocol:", ppt.protocol ); 17 | console::log( "pathname:", ppt.pathname ); 18 | console::log( "search:", ppt.search ); 19 | console::log( "origin:", ppt.origin ); 20 | console::log( "port:", ppt.port ); 21 | console::log( "host:", ppt.host ); 22 | console::log( "hash:", ppt.hash ); 23 | console::log( "user:", ppt.user ); 24 | console::log( "pass:", ppt.pass ); 25 | console::log( "auth:", ppt.auth ); 26 | console::log( "href:", ppt.href ); 27 | 28 | for( auto x : ppt.query.data() ) 29 | console::log( x.first, ":>", x.second ); 30 | 31 | } 32 | 33 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Nodepp C++ Cross-Platform CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build_and_test: 11 | # 1. Define the runners for the matrix strategy 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | os: [ubuntu-latest, macos-latest, windows-latest] 16 | 17 | # 2. Use the matrix variable to set the runner OS 18 | runs-on: ${{ matrix.os }} 19 | 20 | steps: 21 | - name: ⬇️ Checkout code 22 | uses: actions/checkout@v4 23 | 24 | # --- 🧪 Unit Test Compilation and Run --- 25 | 26 | - name: 🧪 Unit Test (Linux/macOS) 27 | # Uses -lssl -lcrypto -lpthread flags 28 | if: runner.os != 'Windows' 29 | run: | 30 | echo "Running Unix-like Unit Test build..." ; cd ./test 31 | g++ -o main main.cpp -I../include -lpthread ; ./main 32 | 33 | - name: 🧪 Unit Test (Windows) 34 | # Uses -lssl -lcrypto -lws2_32 flags 35 | if: runner.os == 'Windows' 36 | run: | 37 | echo "Running Windows Unit Test build..." ; cd ./test 38 | g++ -o main main.cpp -I../include -lws2_32; ./main.exe 39 | 40 | # --- End of the workflow --- 41 | -------------------------------------------------------------------------------- /include/nodepp/mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_MUTEX 13 | #define NODEPP_MUTEX 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "windows/mutex.h" 19 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 20 | #include "posix/mutex.h" 21 | #else 22 | #error "This OS Does not support mutex.h" 23 | #endif 24 | 25 | /*────────────────────────────────────────────────────────────────────────────*/ 26 | 27 | namespace nodepp { namespace mutex { 28 | 29 | template< class T, class... V > 30 | function_t add( mutex_t mut, T cb, const V&... args ){ 31 | return [=](){ return mut.emit( cb, args... ); }; 32 | } 33 | 34 | }} 35 | 36 | /*────────────────────────────────────────────────────────────────────────────*/ 37 | 38 | #endif -------------------------------------------------------------------------------- /include/nodepp/optional.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_OPTIONAL 13 | #define NODEPP_OPTIONAL 14 | 15 | #include "any.h" 16 | 17 | namespace nodepp { 18 | template< class T > class optional_t { 19 | protected: 20 | 21 | bool has; any_t data; 22 | 23 | public: 24 | 25 | optional_t( const T& val ) noexcept { has = true; data = val; } 26 | 27 | optional_t() noexcept { has = false; } 28 | 29 | virtual ~optional_t() noexcept {} 30 | 31 | /*─······································································─*/ 32 | 33 | bool has_value() const noexcept { return has; } 34 | 35 | /*─······································································─*/ 36 | 37 | T value() const { if ( !has_value() || !data.has_value() ) { 38 | throw except_t("Optional does not have a value"); 39 | } return data.as(); } 40 | 41 | };} 42 | 43 | #endif -------------------------------------------------------------------------------- /test/tuple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace TUPLE { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | tuple initialization", [](){ 18 | try { tuple_t tp ( 10, 10.50, "hello world!" ); 19 | if ( tuple::get<0>(tp) != 10 )/*--------*/{ throw 0; } 20 | if ( tuple::get<1>(tp) != 10.50 )/*-----*/{ throw 0; } 21 | if ( tuple::get<2>(tp) != "hello world!" ){ throw 0; } 22 | TEST_DONE(); 23 | } catch ( ... ) { TEST_FAIL(); } 24 | }); 25 | 26 | test.onClose.once([=](){ 27 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 28 | }); 29 | 30 | test.onDone([=](){ (*done)++; (*totl)++; }); 31 | test.onFail([=](){ (*err)++; (*totl)++; }); 32 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 33 | 34 | TEST_AWAIT( test ); 35 | 36 | } 37 | 38 | }} -------------------------------------------------------------------------------- /examples/18-Json_Stringify.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | object_t ppt ({ 9 | 10 | { "var1", 1000 }, 11 | 12 | { "var2", true }, 13 | 14 | { "var3", object_t({ 15 | { "var1", 1000 }, 16 | { "var2", true }, 17 | { "var3", "Hello World!" } 18 | })}, 19 | 20 | { "var4", array_t({ 10, 20, 30, 40, 50 }) }, 21 | 22 | { "var6", array_t({ 23 | object_t({ 24 | { "var1", 1000 }, 25 | { "var2", true }, 26 | { "var3", "Hello World!" } 27 | }), 28 | object_t({ 29 | { "var1", 1000 }, 30 | { "var2", true }, 31 | { "var3", "Hello World!" } 32 | }), 33 | object_t({ 34 | { "var1", 1000 }, 35 | { "var2", true }, 36 | { "var3", "Hello World!" } 37 | }), 38 | })}, 39 | 40 | { "var5", array_t({ 41 | object_t( "Bye World!" ), 42 | object_t( true ), 43 | object_t( 10 ) 44 | })} 45 | 46 | }); 47 | 48 | console::log( json::stringify( ppt ) ); 49 | 50 | } -------------------------------------------------------------------------------- /test/optional.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace OPTION { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | optional -> done", [](){ 18 | try { 19 | optional_t x; 20 | if( x.has_value() ){ TEST_FAIL(); } 21 | TEST_DONE(); 22 | } catch ( ... ) { TEST_FAIL(); } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | optional -> error", [](){ 26 | try { 27 | optional_t x ( "hello world!" ); 28 | if( !x.has_value() ){ TEST_FAIL(); } 29 | TEST_DONE(); 30 | } catch ( ... ) { TEST_FAIL(); } 31 | }); 32 | 33 | test.onClose.once([=](){ 34 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 35 | }); 36 | 37 | test.onDone([=](){ (*done)++; (*totl)++; }); 38 | test.onFail([=](){ (*err)++; (*totl)++; }); 39 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 40 | 41 | TEST_AWAIT( test ); 42 | 43 | } 44 | 45 | }} -------------------------------------------------------------------------------- /test/expected.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace EXPECTED { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | expected -> done", [](){ 18 | try { 19 | expected_t x ( 10 ); 20 | if( !x.has_value() ){ TEST_FAIL(); } 21 | TEST_DONE(); 22 | } catch ( ... ) { TEST_FAIL(); } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | expected -> error", [](){ 26 | try { 27 | expected_t x ( "something went wrong" ); 28 | if( x.has_value() ){ TEST_FAIL(); } 29 | TEST_DONE(); 30 | } catch ( ... ) { TEST_FAIL(); } 31 | }); 32 | 33 | test.onClose.once([=](){ 34 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 35 | }); 36 | 37 | test.onDone([=](){ (*done)++; (*totl)++; }); 38 | test.onFail([=](){ (*err)++; (*totl)++; }); 39 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 40 | 41 | TEST_AWAIT( test ); 42 | 43 | } 44 | 45 | }} -------------------------------------------------------------------------------- /include/nodepp/worker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_WORKER 13 | #define NODEPP_WORKER 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | #include "mutex.h" 19 | #include "windows/worker.h" 20 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 21 | #include "mutex.h" 22 | #include "posix/worker.h" 23 | #else 24 | #error "This OS Does not support worker.h" 25 | #endif 26 | 27 | /*────────────────────────────────────────────────────────────────────────────*/ 28 | 29 | namespace nodepp { namespace worker { 30 | 31 | template< class V, class... T > 32 | void await( V cb, const T&... args ){ 33 | worker_t wrk( cb, args... ); wrk.await(); 34 | } 35 | 36 | template< class V, class... T > 37 | worker_t add( V cb, const T&... args ){ 38 | worker_t wrk( cb, args... ); 39 | wrk.add(); return wrk; 40 | } 41 | 42 | }} 43 | 44 | /*────────────────────────────────────────────────────────────────────────────*/ 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /examples/39-WS-load-test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace nodepp; 10 | 11 | void client( int x ) { 12 | 13 | auto client = ws::client( "ws://localhost:8000/" ); 14 | 15 | client.onConnect([=]( ws_t cli ){ for( auto y=100; y-->0; ){ 16 | 17 | auto raw = type::bind( cli ); 18 | auto stt = type::bind( new int(0) ); 19 | auto idx = type::bind( new int(10) ); 20 | auto wrt = type::bind( _file_::write() ); 21 | 22 | process::add([=](){ auto _state_ = *stt; 23 | gnStart while( (*idx)-->0 ){ 24 | coWait( (*wrt)(&raw,regex::format( "Hello World ${0} ${1} ${2}", x, y, *idx ))==1 ); 25 | } gnStop }); 26 | 27 | }}); 28 | 29 | 30 | } 31 | 32 | void server(){ 33 | 34 | auto server = ws::server(); 35 | 36 | server.onConnect([=]( ws_t cli ){ 37 | 38 | console::log("connected"); 39 | 40 | cli.onData([=]( string_t data ){ 41 | console::log( data ); 42 | }); 43 | 44 | cli.onClose([=](){ 45 | console::log("closed"); 46 | }); 47 | 48 | }); 49 | 50 | server.listen( "localhost", 8000, [=]( socket_t server ){ 51 | console::log("server started at http://localhost:8000"); 52 | }); 53 | 54 | } 55 | 56 | void onMain() { server(); for( auto x=10; x-->0; ){ client(x); } } 57 | -------------------------------------------------------------------------------- /include/nodepp/windows/limit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_WINDOWS_LIMIT 13 | #define NODEPP_WINDOWS_LIMIT 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { namespace limit { ulong _count_=0; 18 | 19 | inline int set_hard_fileno( uint value ) { return _setmaxstdio( value ); } 20 | 21 | inline int set_soft_fileno( uint value ) { return _setmaxstdio( value ); } 22 | 23 | /*─······································································─*/ 24 | 25 | inline uint get_hard_fileno() { return _getmaxstdio(); } 26 | 27 | inline uint get_soft_fileno() { return _getmaxstdio(); } 28 | 29 | /*─······································································─*/ 30 | 31 | inline ulong fileno_count(){ return _count_; } 32 | 33 | inline bool fileno_ready(){ return _count_ < get_soft_fileno(); } 34 | 35 | }} 36 | 37 | /*────────────────────────────────────────────────────────────────────────────*/ 38 | 39 | #endif 40 | 41 | /*────────────────────────────────────────────────────────────────────────────*/ 42 | -------------------------------------------------------------------------------- /examples/53-encoder-utf.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void utf8() { 7 | 8 | ptr_t inp ( "🤯🤬💩" ); 9 | ptr_tu16 ; 10 | ptr_tu32 ; 11 | 12 | u16 = encoder::utf8::to_utf16( inp ); 13 | u32 = encoder::utf8::to_utf32( inp ); 14 | 15 | console::log( "" , string_t( (char*) &inp ) ); 16 | console::log( "", array_t(u16).join() ); 17 | console::log( "", array_t(u32).join() ); 18 | 19 | } 20 | 21 | void utf32() { 22 | 23 | ptr_tinp({ 129327, 129324, 128169, 0x00 }); 24 | ptr_t ui8; 25 | ptr_tu16; 26 | 27 | ui8 = encoder::utf32::to_utf8 ( inp ); 28 | u16 = encoder::utf32::to_utf16( inp ); 29 | 30 | console::log( "" , string_t( (char*) &ui8 ) ); 31 | console::log( "", array_t(u16).join() ); 32 | console::log( "", array_t(inp).join() ); 33 | 34 | } 35 | 36 | void utf16() { 37 | 38 | ptr_tinp({ 55358, 56623, 55358, 56620, 55357, 56489, 0x00 }); 39 | ptr_t ui8; 40 | ptr_tu32; 41 | 42 | ui8 = encoder::utf16::to_utf8 ( inp ); 43 | u32 = encoder::utf16::to_utf32( inp ); 44 | 45 | console::log( "" , string_t( (char*) &ui8 ) ); 46 | console::log( "", array_t(inp).join() ); 47 | console::log( "", array_t(u32).join() ); 48 | 49 | } 50 | 51 | void onMain(){ 52 | 53 | utf8 (); console::log("---"); 54 | utf16(); console::log("---"); 55 | utf32(); 56 | 57 | } -------------------------------------------------------------------------------- /include/nodepp/expected.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_EXPECTED 13 | #define NODEPP_EXPECTED 14 | 15 | #include "any.h" 16 | 17 | namespace nodepp { 18 | template struct expected_t { 19 | protected: 20 | 21 | bool has; any_t data; 22 | 23 | public: 24 | 25 | expected_t( const T& val ) { has = true; data = val; } 26 | 27 | expected_t( const E& err ) { has = false;data = err; } 28 | 29 | virtual ~expected_t() noexcept {} 30 | 31 | /*─······································································─*/ 32 | 33 | bool has_value() const noexcept { return has; } 34 | 35 | /*─······································································─*/ 36 | 37 | T value() const { if ( !has_value() || !data.has_value() ) { 38 | throw except_t("expected does not have a value"); 39 | } return data.as(); } 40 | 41 | /*─······································································─*/ 42 | 43 | E error() const { if ( has_value() || !data.has_value() ) { 44 | throw except_t("expected does not have a value"); 45 | } return data.as(); } 46 | 47 | };} 48 | 49 | #endif -------------------------------------------------------------------------------- /test/function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace FUNCTION { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | function initialization 1", [](){ 18 | try { 19 | function_t clb ([=](){ return 1; }); 20 | if ( clb.empty() ){ throw 0; } 21 | if ( clb() != 1 ){ throw 0; } 22 | TEST_DONE(); 23 | } catch ( ... ) { TEST_FAIL(); } 24 | }); 25 | 26 | TEST_ADD( test, "TEST 2 | function initialization 2", [](){ 27 | try { 28 | function_t clb ([=]( int x ){ return x; }); 29 | if ( clb.empty() ){ throw 0; } 30 | if ( clb(1) != 1 ){ throw 0; } 31 | TEST_DONE(); 32 | } catch ( ... ) { TEST_FAIL(); } 33 | }); 34 | 35 | test.onClose.once([=](){ 36 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 37 | }); 38 | 39 | test.onDone([=](){ (*done)++; (*totl)++; }); 40 | test.onFail([=](){ (*err)++; (*totl)++; }); 41 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 42 | 43 | TEST_AWAIT( test ); 44 | 45 | } 46 | 47 | }} -------------------------------------------------------------------------------- /examples/17-Json.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | void onMain(){ 7 | 8 | object_t ppt ({ 9 | 10 | { "var1", 1000 }, 11 | 12 | { "var2", true }, 13 | 14 | { "var3", object_t({ 15 | { "var1", 1000 }, 16 | { "var2", true }, 17 | { "var3", "Hello World!" } 18 | })}, 19 | 20 | { "var4", array_t({ 10, 20, 30, 40, 50 }) }, 21 | 22 | { "var6", array_t({ 23 | object_t({ 24 | { "var1", 1000 }, 25 | { "var2", true }, 26 | { "var3", "Hello World!" } 27 | }), 28 | object_t({ 29 | { "var1", 1000 }, 30 | { "var2", true }, 31 | { "var3", "Hello World!" } 32 | }), 33 | object_t({ 34 | { "var1", 1000 }, 35 | { "var2", true }, 36 | { "var3", "Hello World!" } 37 | }), 38 | })}, 39 | 40 | { "var5", array_t({ 41 | object_t( "Bye World!" ), 42 | object_t( true ), 43 | object_t( 10 ) 44 | })} 45 | 46 | }); 47 | 48 | console::log( ppt["var1"].as() ); 49 | console::log( ppt["var2"].as() ? "true" : "false" ); 50 | 51 | console::log( ppt["var3"]["var1"].as() ); 52 | console::log( ppt["var4"].as>().join() ); 53 | 54 | console::log( ppt["var5"][0].as() ); 55 | console::log( ppt["var6"][0]["var3"].as() ); 56 | 57 | } -------------------------------------------------------------------------------- /test/file.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace nodepp; 7 | 8 | namespace TEST { namespace FILE { 9 | 10 | void TEST_RUNNER(){ 11 | ptr_t totl = new uint(0); 12 | ptr_t done = new uint(0); 13 | ptr_t err = new uint(0); 14 | ptr_t skp = new uint(0); 15 | 16 | auto test = TEST_CREATE(); 17 | 18 | TEST_ADD( test, "TEST 1 | file write", [](){ 19 | try { file_t file( "test_file", "w" ); 20 | file.write ( "hello world!" ); 21 | if ( !fs::exists_file( "test_file" ) ) 22 | { throw 0; } TEST_DONE(); 23 | } catch ( ... ) { TEST_FAIL(); } 24 | }); 25 | 26 | TEST_ADD( test, "TEST 2 | file read", [](){ 27 | try { file_t file( "test_file", "r" ); 28 | auto data = file.read(); 29 | if ( data != "hello world!" ) 30 | { throw 0; } TEST_DONE(); 31 | } catch ( ... ) { TEST_FAIL(); } 32 | }); 33 | 34 | TEST_ADD( test, "TEST 3 | file delete", [](){ 35 | try{ fs::remove_file( "test_file" ); 36 | if ( fs::exists_file( "test_file" ) ) 37 | { throw 0; } TEST_DONE(); 38 | } catch ( ... ) { TEST_FAIL(); } 39 | }); 40 | 41 | test.onClose.once([=](){ 42 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 43 | }); 44 | 45 | test.onDone([=](){ (*done)++; (*totl)++; }); 46 | test.onFail([=](){ (*err)++; (*totl)++; }); 47 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 48 | 49 | TEST_AWAIT( test ); 50 | 51 | } 52 | 53 | }} -------------------------------------------------------------------------------- /include/nodepp/cookie.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_COOKIE 13 | #define NODEPP_COOKIE 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include "regex.h" 18 | #include "map.h" 19 | 20 | /*────────────────────────────────────────────────────────────────────────────*/ 21 | 22 | namespace nodepp { using cookie_t = map_t< string_t, string_t >; 23 | namespace cookie { 24 | 25 | inline query_t parse( string_t data ){ 26 | static regex_t reg( "([^= ;]+)=([^;]+)" ); 27 | 28 | if( data.empty() ){ return query_t(); } query_t out; 29 | 30 | reg.search_all( data ); auto mem = reg.get_memory(); 31 | reg.clear_memory(); 32 | 33 | while( !mem.empty() ){ auto data = mem.splice( 0, 2 ); 34 | if( data.size()!=2 ){ break; } 35 | out[ data[0] ] = data[1]; 36 | } return out; 37 | } 38 | 39 | /*─······································································─*/ 40 | 41 | inline string_t format( const cookie_t& data ){ 42 | if( data.empty() ){ return nullptr; } /*------*/ 43 | array_t out; for( auto x:data.data() ) 44 | { out.push( x.first + "=" + x.second ); } 45 | return string::format("%s",out.join("; ").c_str()); 46 | } 47 | 48 | }} 49 | 50 | /*────────────────────────────────────────────────────────────────────────────*/ 51 | 52 | #endif -------------------------------------------------------------------------------- /include/nodepp/query.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_QUERY 13 | #define NODEPP_QUERY 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include "regex.h" 18 | #include "map.h" 19 | 20 | /*────────────────────────────────────────────────────────────────────────────*/ 21 | 22 | namespace nodepp { using query_t = map_t< string_t, string_t >; 23 | namespace query { 24 | 25 | inline query_t parse( string_t data ){ 26 | static regex_t reg("[?&]([^= ]+)=([^?&]+)"); 27 | 28 | if( data.empty() || data[0]!='?' ){ return query_t(); } query_t out; 29 | 30 | reg.search_all( data ); auto mem = reg.get_memory(); 31 | reg.clear_memory(); 32 | 33 | while( !mem.empty() ){ auto data = mem.splice( 0, 2 ); 34 | if( data.size()!=2 ){ break; } 35 | out[ data[0] ] = data[1]; 36 | } return out; 37 | } 38 | 39 | /*─······································································─*/ 40 | 41 | inline string_t format( const query_t& data ){ 42 | if( data.empty() ){ return nullptr; } /*------*/ 43 | array_t out; for( auto x:data.data() ) 44 | { out.push( x.first + "=" + x.second ); } 45 | return string::format("?%s",out.join("&").c_str()); 46 | } 47 | 48 | }} 49 | 50 | /*────────────────────────────────────────────────────────────────────────────*/ 51 | 52 | #endif -------------------------------------------------------------------------------- /examples/46-TCP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void server(){ 8 | 9 | auto server = tcp::server(); 10 | 11 | server.onConnect([=]( socket_t cli ){ 12 | 13 | console::log("connected" ); 14 | auto cin = fs::std_input(); 15 | 16 | cli.onData([=]( string_t data ){ 17 | console::log( data ); 18 | }); 19 | 20 | cin.onData([=]( string_t data ){ 21 | cli.write( data ); 22 | }); 23 | 24 | cli.onDrain.once([=](){ 25 | console::log("closed"); 26 | cin.close(); 27 | }); 28 | 29 | stream::pipe( cli ); 30 | stream::pipe( cin ); 31 | 32 | }); 33 | 34 | server.listen( "localhost", 8000, []( socket_t srv ){ 35 | console::log("-> tcp://localhost:8000"); 36 | }); 37 | 38 | } 39 | 40 | void client(){ 41 | 42 | auto client = tcp::client(); 43 | 44 | client.onOpen([=]( socket_t cli ){ 45 | 46 | console::log("connected" ); 47 | auto cin = fs::std_input(); 48 | 49 | cli.onData([=]( string_t data ){ 50 | console::log( data ); 51 | }); 52 | 53 | cin.onData([=]( string_t data ){ 54 | cli.write( data ); 55 | }); 56 | 57 | cli.onDrain.once([=](){ 58 | console::log("closed"); 59 | cin.close(); 60 | }); 61 | 62 | stream::pipe( cli ); 63 | stream::pipe( cin ); 64 | 65 | }); 66 | 67 | client.connect( "localhost", 8000, []( socket_t cli ){ 68 | console::log("-> tcp://localhost:8000"); 69 | }); 70 | 71 | } 72 | 73 | void onMain() { 74 | 75 | if( process::env::get("mode")=="client" ) 76 | { client(); } else { server(); } 77 | 78 | } 79 | 80 | // g++ -o main main.cpp -I./include ; ./main ?mode=client -------------------------------------------------------------------------------- /examples/48-UDP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void server(){ 8 | 9 | auto server = udp::server(); 10 | 11 | server.onConnect([=]( socket_t cli ){ 12 | 13 | console::log("connected" ); 14 | auto cin = fs::std_input(); 15 | 16 | cli.onData([=]( string_t data ){ 17 | console::log( data ); 18 | }); 19 | 20 | cin.onData([=]( string_t data ){ 21 | cli.write( data ); 22 | }); 23 | 24 | cli.onDrain.once([=](){ 25 | console::log("closed"); 26 | cin.close(); 27 | }); 28 | 29 | stream::pipe( cli ); 30 | stream::pipe( cin ); 31 | 32 | }); 33 | 34 | server.listen( "localhost", 8000, []( socket_t srv ){ 35 | console::log("-> tcp://localhost:8000"); 36 | }); 37 | 38 | } 39 | 40 | void client(){ 41 | 42 | auto client = udp::client(); 43 | 44 | client.onConnect([=]( socket_t cli ){ 45 | 46 | console::log("connected" ); 47 | auto cin = fs::std_input(); 48 | 49 | cli.onData([=]( string_t data ){ 50 | console::log( data ); 51 | }); 52 | 53 | cin.onData([=]( string_t data ){ 54 | cli.write( data ); 55 | }); 56 | 57 | cli.onDrain.once([=](){ 58 | console::log("closed"); 59 | cin.close(); 60 | }); 61 | 62 | stream::pipe( cli ); 63 | stream::pipe( cin ); 64 | 65 | }); 66 | 67 | client.connect( "localhost", 8000, []( socket_t cli ){ 68 | console::log("-> udp://localhost:8000"); 69 | }); 70 | 71 | } 72 | 73 | void onMain() { 74 | 75 | if( process::env::get("mode")=="client" ) 76 | { client(); } else { server(); } 77 | 78 | } 79 | 80 | // g++ -o main main.cpp -I./include ; ./main ?mode=client -------------------------------------------------------------------------------- /include/nodepp/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_DEBUG 13 | #define NODEPP_DEBUG 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { class debug_t { 18 | protected: 19 | 20 | struct NODE { 21 | string_t msg; 22 | void* ev = nullptr; 23 | }; ptr_t obj; 24 | 25 | public: debug_t() noexcept : obj(new NODE()) { } 26 | 27 | /*─······································································─*/ 28 | 29 | virtual ~debug_t() noexcept { 30 | if ( obj.count() == 2 ){ 31 | console::log( obj->msg, "closed" ); 32 | } process::onSIGERR.off( obj->ev ); 33 | } 34 | 35 | /*─······································································─*/ 36 | 37 | debug_t( const string_t& msg ) noexcept : obj(new NODE()) { 38 | obj->msg = msg; auto inp = type::bind( this ); 39 | obj->ev = process::onSIGERR([=](){ inp->error(); }); 40 | console::log( obj->msg, "open" ); 41 | } 42 | 43 | /*─······································································─*/ 44 | 45 | template< class... T > 46 | void log( const T&... args ) const noexcept { console::log( "--", args... ); } 47 | 48 | void error() const noexcept { console::error( obj->msg ); } 49 | 50 | };} 51 | 52 | /*────────────────────────────────────────────────────────────────────────────*/ 53 | 54 | #endif -------------------------------------------------------------------------------- /examples/50-TLS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | void server(){ 8 | 9 | auto ssl = ssl_t(); 10 | auto server = tls::server( &ssl ); 11 | 12 | server.onConnect([=]( ssocket_t cli ){ 13 | 14 | console::log("connected" ); 15 | auto cin = fs::std_input(); 16 | 17 | cli.onData([=]( string_t data ){ 18 | console::log( data ); 19 | }); 20 | 21 | cin.onData([=]( string_t data ){ 22 | cli.write( data ); 23 | }); 24 | 25 | cli.onDrain.once([=](){ 26 | console::log("closed"); 27 | cin.close(); 28 | }); 29 | 30 | stream::pipe( cli ); 31 | stream::pipe( cin ); 32 | 33 | }); 34 | 35 | server.listen( "localhost", 8000, []( ssocket_t ){ 36 | console::log("-> tls://localhost:8000"); 37 | }); 38 | 39 | } 40 | 41 | void client(){ 42 | 43 | auto ssl = ssl_t(); 44 | auto client = tls::client( &ssl ); 45 | 46 | client.onConnect([=]( ssocket_t cli ){ 47 | 48 | console::log("connected" ); 49 | auto cin = fs::std_input(); 50 | 51 | cli.onData([=]( string_t data ){ 52 | console::log( data ); 53 | }); 54 | 55 | cin.onData([=]( string_t data ){ 56 | cli.write( data ); 57 | }); 58 | 59 | cli.onDrain.once([=](){ 60 | console::log("closed"); 61 | cin.close(); 62 | }); 63 | 64 | stream::pipe( cli ); 65 | stream::pipe( cin ); 66 | 67 | }); 68 | 69 | client.connect( "localhost", 8000, []( socket_t cli ){ 70 | console::log("-> tls://localhost:8000"); 71 | }); 72 | 73 | } 74 | 75 | void onMain() { 76 | 77 | if( process::env::get("mode")=="client" ) 78 | { client(); } else { server(); } 79 | 80 | } 81 | 82 | // g++ -o main main.cpp -I./include ; ./main ?mode=client -------------------------------------------------------------------------------- /include/nodepp/import.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_IMPORT 13 | #define NODEPP_IMPORT 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | /*────────────────────────────────────────────────────────────────────────────*/ 24 | 25 | #include "macros.h" 26 | #include "type.h" 27 | #include "atomic.h" 28 | 29 | /*────────────────────────────────────────────────────────────────────────────*/ 30 | 31 | #include "ptr.h" 32 | #include "ref.h" 33 | 34 | /*────────────────────────────────────────────────────────────────────────────*/ 35 | 36 | #include "iterator.h" 37 | #include "function.h" 38 | #include "queue.h" 39 | 40 | /*────────────────────────────────────────────────────────────────────────────*/ 41 | 42 | #include "coroutine.h" 43 | #include "string.h" 44 | #include "array.h" 45 | 46 | /*────────────────────────────────────────────────────────────────────────────*/ 47 | 48 | #include "iterator.h" 49 | #include "console.h" 50 | #include "sleep.h" 51 | 52 | /*────────────────────────────────────────────────────────────────────────────*/ 53 | 54 | #include "loop.h" 55 | #include "signal.h" 56 | #include "except.h" 57 | 58 | /*────────────────────────────────────────────────────────────────────────────*/ 59 | 60 | #include "query.h" 61 | #include "poll.h" 62 | 63 | /*────────────────────────────────────────────────────────────────────────────*/ 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /test/loop.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace LOOP { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | EVloop initialization", [](){ 18 | try { loop_t ev; ptr_t x = new int(0); 19 | ev.add([=](){ *x = 10; return -1; }); 20 | ev.next(); 21 | if ( *x != 10 ){ throw 0; } 22 | TEST_DONE(); 23 | } catch ( ... ) { TEST_FAIL(); } 24 | }); 25 | 26 | TEST_ADD( test, "TEST 1 | EVloop iteration 1", [](){ 27 | try { loop_t ev; ptr_t x = new int(0); 28 | ev.add([=](){ *x += 10; return 1; }); 29 | ev.next(); ev.next(); ev.next(); 30 | if ( *x != 30 ){ throw 0; } 31 | TEST_DONE(); 32 | } catch ( ... ) { TEST_FAIL(); } 33 | }); 34 | 35 | TEST_ADD( test, "TEST 1 | EVloop iteration 2", [](){ 36 | try { loop_t ev; ptr_t x = new int(0); 37 | ev.add([=](){ *x += 10; return -1; }); 38 | ev.next(); ev.next(); ev.next(); 39 | if ( *x != 10 ){ throw 0; } 40 | TEST_DONE(); 41 | } catch ( ... ) { TEST_FAIL(); } 42 | }); 43 | 44 | test.onClose.once([=](){ 45 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 46 | }); 47 | 48 | test.onDone([=](){ (*done)++; (*totl)++; }); 49 | test.onFail([=](){ (*err)++; (*totl)++; }); 50 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 51 | 52 | TEST_AWAIT( test ); 53 | 54 | } 55 | 56 | }} -------------------------------------------------------------------------------- /test/ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | namespace TEST { namespace PTR { 7 | 8 | void TEST_RUNNER(){ 9 | ptr_t totl = new uint(0); 10 | ptr_t done = new uint(0); 11 | ptr_t err = new uint(0); 12 | ptr_t skp = new uint(0); 13 | 14 | auto test = TEST_CREATE(); 15 | 16 | TEST_ADD( test, "TEST 1 | ptr initialization 1", [](){ 17 | try { 18 | ptr_t arr ({ 10, 50, 90, 20 }); 19 | if ( arr.size() != 4 ){ throw 0; } 20 | if ( arr[0] !=10 ){ throw 0; } 21 | if ( arr[1] !=50 ){ throw 0; } 22 | if ( arr[2] !=90 ){ throw 0; } 23 | if ( arr[3] !=20 ){ throw 0; } 24 | if ( arr[4] !=10 ){ throw 0; } 25 | TEST_DONE(); 26 | } catch ( ... ) { TEST_FAIL(); } 27 | }); 28 | 29 | TEST_ADD( test, "TEST 1 | ptr initialization 2", [](){ 30 | try { 31 | ptr_t arr ( new uint(1000) ); 32 | if ( *arr != 1000 ){ throw 0; } 33 | TEST_DONE(); 34 | } catch ( ... ) { TEST_FAIL(); } 35 | }); 36 | 37 | TEST_ADD( test, "TEST 12 | ptr clearing", [](){ 38 | try { 39 | ptr_t arr ({ 10, 20, 30 }); 40 | arr = nullptr; 41 | if ( !arr.null() ){ throw 0; } 42 | TEST_DONE(); 43 | } catch ( ... ) { TEST_FAIL(); } 44 | }); 45 | 46 | test.onClose.once([=](){ 47 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 48 | }); 49 | 50 | test.onDone([=](){ (*done)++; (*totl)++; }); 51 | test.onFail([=](){ (*err)++; (*totl)++; }); 52 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 53 | 54 | TEST_AWAIT( test ); 55 | 56 | } 57 | 58 | }} -------------------------------------------------------------------------------- /include/nodepp/posix/sleep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_POSIX_SLEEP 13 | #define NODEPP_POSIX_SLEEP 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | #include 19 | 20 | /*────────────────────────────────────────────────────────────────────────────*/ 21 | 22 | namespace nodepp { namespace process { using NODE_INTERVAL = struct timeval; } } 23 | namespace nodepp { namespace process { 24 | 25 | inline NODE_INTERVAL get_new_interval(){ NODE_INTERVAL interval; 26 | gettimeofday( &interval, NULL ); 27 | return interval; 28 | } 29 | 30 | inline ulong micros(){ NODE_INTERVAL time = get_new_interval(); 31 | return time.tv_sec * 1000000 + time.tv_usec; 32 | } 33 | 34 | inline ulong seconds(){ NODE_INTERVAL time = get_new_interval(); 35 | return time.tv_sec + time.tv_usec / 1000000; 36 | } 37 | 38 | inline ulong millis(){ NODE_INTERVAL time = get_new_interval(); 39 | return time.tv_sec * 1000 + time.tv_usec / 1000; 40 | } 41 | 42 | }} 43 | 44 | /*────────────────────────────────────────────────────────────────────────────*/ 45 | 46 | namespace nodepp { namespace process { 47 | 48 | inline void delay( ulong time ){ ::usleep( time * 1000 ); } 49 | 50 | inline void yield(){ delay( TIMEOUT ); } 51 | 52 | inline ulong now(){ return millis(); } 53 | 54 | }} 55 | 56 | /*────────────────────────────────────────────────────────────────────────────*/ 57 | 58 | #endif 59 | 60 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /test/worker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace WORKER { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | async worker testing", [](){ 18 | try { ptr_t x = new int(0); 19 | ptr_t y = new int(3); 20 | 21 | worker::add( coroutine::add( COROUTINE(){ 22 | coBegin 23 | 24 | while( *y>0 ){ *x += 10; *y-=1; coNext; } 25 | 26 | coFinish 27 | })); 28 | 29 | while( *y!=0 ){ process::next(); } 30 | if( *x != 30 ){ TEST_FAIL(); } 31 | TEST_DONE(); 32 | } catch ( ... ) { TEST_FAIL(); } 33 | }); 34 | 35 | TEST_ADD( test, "TEST 2 | sync worker testing", [](){ 36 | try { ptr_t x = new int(0); 37 | ptr_t y = new int(3); 38 | 39 | worker::await( coroutine::add( COROUTINE(){ 40 | coBegin 41 | 42 | while( *y>0 ){ *x += 10; *y-=1; coNext; } 43 | 44 | coFinish 45 | })); 46 | 47 | if( *x != 30 ){ TEST_FAIL(); } 48 | TEST_DONE(); 49 | } catch ( ... ) { TEST_FAIL(); } 50 | }); 51 | 52 | test.onClose.once([=](){ 53 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 54 | }); 55 | 56 | test.onDone([=](){ (*done)++; (*totl)++; }); 57 | test.onFail([=](){ (*err)++; (*totl)++; }); 58 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 59 | 60 | TEST_AWAIT( test ); 61 | 62 | } 63 | 64 | }} -------------------------------------------------------------------------------- /test/dns.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace DNS { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | dns -> IPv6", [](){ 18 | try { 19 | string_t data = "2001:0DB8:85A3:0000:0000:8A2E:0370:7334"; 20 | if( dns::is_ipv6(data) ){ TEST_DONE(); } 21 | TEST_FAIL(); 22 | } catch ( ... ) { TEST_FAIL(); } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | dns -> IPv4", [](){ 26 | try { 27 | string_t data = "192.168.0.1"; 28 | if( dns::is_ipv4(data) ){ TEST_DONE(); } 29 | TEST_FAIL(); 30 | } catch ( ... ) { TEST_FAIL(); } 31 | }); 32 | 33 | TEST_ADD( test, "TEST 3 | dns -> IPv6 fail test", [](){ 34 | try { 35 | string_t data = "mojon"; 36 | if( dns::is_ipv6(data) ){ TEST_FAIL(); } 37 | TEST_DONE(); 38 | } catch ( ... ) { TEST_FAIL(); } 39 | }); 40 | 41 | TEST_ADD( test, "TEST 4 | dns -> IPv4 fail test", [](){ 42 | try { 43 | string_t data = "mojon"; 44 | if( dns::is_ipv4(data) ){ TEST_FAIL(); } 45 | TEST_DONE(); 46 | } catch ( ... ) { TEST_FAIL(); } 47 | }); 48 | 49 | test.onClose.once([=](){ 50 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 51 | }); 52 | 53 | test.onDone([=](){ (*done)++; (*totl)++; }); 54 | test.onFail([=](){ (*err)++; (*totl)++; }); 55 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 56 | 57 | TEST_AWAIT( test ); 58 | 59 | } 60 | 61 | }} -------------------------------------------------------------------------------- /include/nodepp/posix/limit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_POSIX_LIMIT 13 | #define NODEPP_POSIX_LIMIT 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | namespace nodepp { namespace limit { ulong _count_=0; 22 | 23 | inline uint get_hard_fileno() { struct rlimit limit; 24 | if( getrlimit( RLIMIT_NOFILE, &limit )==0 ) 25 | { return limit.rlim_max; } return 1024; 26 | } 27 | 28 | inline uint get_soft_fileno() { struct rlimit limit; 29 | if( getrlimit( RLIMIT_NOFILE, &limit )==0 ) 30 | { return limit.rlim_cur; } return 1024; 31 | } 32 | 33 | inline int set_hard_fileno( uint value ) { 34 | struct rlimit limit; 35 | limit.rlim_max = value; 36 | limit.rlim_cur = get_soft_fileno(); 37 | return setrlimit( RLIMIT_NOFILE, &limit ); 38 | } 39 | 40 | inline int set_soft_fileno( uint value ) { 41 | struct rlimit limit; 42 | limit.rlim_cur = value; 43 | limit.rlim_max = get_hard_fileno(); 44 | return setrlimit( RLIMIT_NOFILE, &limit ); 45 | } 46 | 47 | /*─······································································─*/ 48 | 49 | inline ulong fileno_count(){ return _count_; } 50 | 51 | inline bool fileno_ready(){ return _count_ < get_soft_fileno(); } 52 | 53 | }} 54 | 55 | /*────────────────────────────────────────────────────────────────────────────*/ 56 | 57 | #endif 58 | 59 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /include/nodepp/ssocket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_SSCOKET 13 | #define NODEPP_SSCOKET 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include "socket.h" 18 | #include "ssl.h" 19 | #include "fs.h" 20 | 21 | /*────────────────────────────────────────────────────────────────────────────*/ 22 | 23 | namespace nodepp { 24 | 25 | class ssocket_t : public socket_t { 26 | public: ptr_t ssl; 27 | 28 | /*─······································································─*/ 29 | 30 | ssocket_t( ssl_t ssl, int df, ulong size=CHUNK_SIZE ) noexcept : 31 | socket_t( df, size ), ssl( new ssl_t( ssl, df ) ) {} 32 | 33 | ssocket_t() noexcept : socket_t(), ssl( new ssl_t() ) {} 34 | 35 | virtual ~ssocket_t() noexcept {} 36 | 37 | /*─······································································─*/ 38 | 39 | virtual int __read( char* bf, const ulong& sx ) const noexcept override { 40 | if ( process::millis() > get_recv_timeout() || is_closed() ) 41 | { return -1; } if ( sx==0 ) { return 0; } 42 | if ( ssl.null() ) /*--------*/ { return -1; } 43 | obj->feof = ssl->_read( bf, sx ); return obj->feof; 44 | } 45 | 46 | virtual int __write( char* bf, const ulong& sx ) const noexcept override { 47 | if ( process::millis() > get_send_timeout() || is_closed() ) 48 | { return -1; } if ( sx==0 ) { return 0; } 49 | if ( ssl.null() ) /*--------*/ { return -1; } 50 | obj->feof = ssl->_write( bf,sx ); return obj->feof; 51 | } 52 | 53 | };} 54 | 55 | /*────────────────────────────────────────────────────────────────────────────*/ 56 | 57 | #endif -------------------------------------------------------------------------------- /test/path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace PATH { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | path mimetype", [](){ 18 | try { string_t dir = path::join( os::cwd(), "www", "index.html" ); 19 | if ( path::mimetype(dir) != "text/html" ){ throw 0; } 20 | TEST_DONE(); 21 | } catch ( ... ) { TEST_FAIL(); } 22 | }); 23 | 24 | TEST_ADD( test, "TEST 2 | path basename", [](){ 25 | try { string_t dir = path::join( os::cwd(), "www", "index.html" ); 26 | if ( path::basename(dir,".html") != "index" ){ throw 0; } 27 | TEST_DONE(); 28 | } catch ( ... ) { TEST_FAIL(); } 29 | }); 30 | 31 | TEST_ADD( test, "TEST 3 | path name", [](){ 32 | try { string_t dir = path::join( os::cwd(), "www", "index.html" ); 33 | if ( path::basename(dir) != "index.html" ){ throw 0; } 34 | TEST_DONE(); 35 | } catch ( ... ) { TEST_FAIL(); } 36 | }); 37 | 38 | TEST_ADD( test, "TEST 4 | path extention", [](){ 39 | try { string_t dir = path::join( os::cwd(), "www", "index.html" ); 40 | if ( path::extname(dir) != "html" ){ throw 0; } 41 | TEST_DONE(); 42 | } catch ( ... ) { TEST_FAIL(); } 43 | }); 44 | 45 | test.onClose.once([=](){ 46 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 47 | }); 48 | 49 | test.onDone([=](){ (*done)++; (*totl)++; }); 50 | test.onFail([=](){ (*err)++; (*totl)++; }); 51 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 52 | 53 | TEST_AWAIT( test ); 54 | 55 | } 56 | 57 | }} -------------------------------------------------------------------------------- /test/cookie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace COOKIE { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | cookie initialization", [](){ 18 | try { cookie_t cookie = nodepp::cookie::parse( "var1=10; var2=20; var3=30" ); 19 | if ( cookie.size() != 3 )/**/{ throw 0; } 20 | if ( cookie["var1"] != "10" ){ throw 0; } 21 | TEST_DONE(); 22 | } catch ( ... ) { TEST_FAIL(); } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | cookie searching", [](){ 26 | try { 27 | cookie_t cookie ({ 28 | { "var1", "10" }, 29 | { "var2", "20" }, 30 | { "var3", "30" } 31 | }); 32 | if ( !cookie.has("var1") ){ throw 0; } 33 | TEST_DONE(); 34 | } catch ( ... ) { TEST_FAIL(); } 35 | }); 36 | 37 | TEST_ADD( test, "TEST 3 | cookie parsing", [](){ 38 | try { 39 | string_t out = cookie::format( cookie_t({ 40 | { "var1", "10" }, 41 | { "var2", "20" }, 42 | { "var3", "30" } 43 | }) ); 44 | if( out!="var1=10; var2=20; var3=30" ){ throw 0; } 45 | TEST_DONE(); 46 | } catch ( ... ) { TEST_FAIL(); } 47 | }); 48 | 49 | test.onClose.once([=](){ 50 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 51 | }); 52 | 53 | test.onDone([=](){ (*done)++; (*totl)++; }); 54 | test.onFail([=](){ (*err)++; (*totl)++; }); 55 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 56 | 57 | TEST_AWAIT( test ); 58 | 59 | } 60 | 61 | }} -------------------------------------------------------------------------------- /examples/38-WS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace nodepp; 9 | 10 | void server(){ 11 | 12 | auto server = http::server([=]( http_t cli ){ 13 | 14 | cli.write_header( 200, header_t({ 15 | { "Content-Security-Policy", "*" } 16 | }) ); 17 | 18 | cli.write("Hello World!"); 19 | 20 | }); ws::server( server ); 21 | 22 | server.onConnect([=]( ws_t cli ){ 23 | 24 | auto cin = fs::std_input(); 25 | console::log("connected"); 26 | 27 | cin.onData([=]( string_t data ){ 28 | cli.write( data ); 29 | }); 30 | 31 | cli.onData([=]( string_t data ){ 32 | console::log( "serv:", data ); 33 | }); 34 | 35 | cli.onDrain([=](){ 36 | console::log("closed"); 37 | cin.close(); 38 | }); 39 | 40 | stream::pipe( cin ); 41 | 42 | }); 43 | 44 | server.listen( "localhost", 8000, [=]( socket_t server ){ 45 | console::log("server started at http://localhost:8000"); 46 | }); 47 | 48 | } 49 | 50 | void client() { 51 | 52 | auto client = ws::client( "ws://localhost:8000/" ); 53 | 54 | client.onConnect([=]( ws_t cli ){ 55 | 56 | auto cin = fs::std_input(); 57 | console::log("connected"); 58 | 59 | cli.onData([]( string_t chunk ){ 60 | console::log("cli:", chunk); 61 | }); 62 | 63 | cin.onData([=]( string_t data ){ 64 | cli.write( data ); 65 | }); 66 | 67 | cli.onDrain([=](){ 68 | console::log("closed"); 69 | cin.close(); 70 | }); 71 | 72 | stream::pipe( cin ); 73 | 74 | }); 75 | 76 | client.onError([=]( except_t err ){ 77 | console::log( "<>", err.data() ); 78 | }); 79 | 80 | } 81 | 82 | void onMain() { 83 | 84 | if( process::env::get("mode")=="client" ) 85 | { client(); } else { server(); } 86 | 87 | } 88 | 89 | // g++ -o main main.cpp -I./include ; ./main ?mode=client -------------------------------------------------------------------------------- /test/query.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace QUERY { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | query initialization", [](){ 18 | try { 19 | query_t query = nodepp::query::parse( "?var1=10&var2=20&var3=30" ); 20 | if ( query.size() != 3 )/**/{ throw 0; } 21 | if ( query["var1"] != "10" ){ throw 0; } 22 | TEST_DONE(); 23 | } catch ( ... ) { TEST_FAIL(); } 24 | }); 25 | 26 | TEST_ADD( test, "TEST 2 | query searching", [](){ 27 | try { 28 | query_t query ({ 29 | { "var1", "10" }, 30 | { "var2", "20" }, 31 | { "var3", "30" } 32 | }); 33 | if ( !query.has("var1") ){ throw 0; } 34 | TEST_DONE(); 35 | } catch ( ... ) { TEST_FAIL(); } 36 | }); 37 | 38 | TEST_ADD( test, "TEST 3 | query parsing", [](){ 39 | try { 40 | string_t out = query::format( query_t({ 41 | { "var1", "10" }, 42 | { "var2", "20" }, 43 | { "var3", "30" } 44 | }) ); 45 | if( out!="?var1=10&var2=20&var3=30" ){ throw 0; } 46 | TEST_DONE(); 47 | } catch ( ... ) { TEST_FAIL(); } 48 | }); 49 | 50 | test.onClose.once([=](){ 51 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 52 | }); 53 | 54 | test.onDone([=](){ (*done)++; (*totl)++; }); 55 | test.onFail([=](){ (*err)++; (*totl)++; }); 56 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 57 | 58 | TEST_AWAIT( test ); 59 | 60 | } 61 | 62 | }} -------------------------------------------------------------------------------- /test/atomic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace ATOMIC { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | atomic -> initialization", [](){ 18 | try { 19 | atomic_t x( 10 ); 20 | if( x== 10 ){ TEST_DONE(); } 21 | TEST_FAIL(); 22 | } catch ( ... ) { TEST_FAIL(); } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | atomic -> add", [](){ 26 | try { 27 | atomic_t x( 10 ); x += 10; 28 | if( x== 20 ){ TEST_DONE(); } 29 | TEST_FAIL(); 30 | } catch ( ... ) { TEST_FAIL(); } 31 | }); 32 | 33 | TEST_ADD( test, "TEST 3 | atomic -> sub", [](){ 34 | try { 35 | atomic_t x( 10 ); x -= 5; 36 | if( x == 5 ){ TEST_DONE(); } 37 | TEST_FAIL(); 38 | } catch ( ... ) { TEST_FAIL(); } 39 | }); 40 | 41 | TEST_ADD( test, "TEST 4 | atomic -> swap", [](){ 42 | try { 43 | 44 | atomic_t x( 10 ); 45 | auto y = x.swap(20); 46 | auto z = x.get(); 47 | 48 | if( y!= 10 ){ TEST_FAIL(); } 49 | if( z!= 20 ){ TEST_FAIL(); } 50 | TEST_DONE(); 51 | } catch ( ... ) { TEST_FAIL(); } 52 | }); 53 | 54 | test.onClose.once([=](){ 55 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 56 | }); 57 | 58 | test.onDone([=](){ (*done)++; (*totl)++; }); 59 | test.onFail([=](){ (*err)++; (*totl)++; }); 60 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 61 | 62 | TEST_AWAIT( test ); 63 | 64 | } 65 | 66 | }} -------------------------------------------------------------------------------- /include/nodepp/windows/sleep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_WINDOWS_SLEEP 13 | #define NODEPP_WINDOWS_SLEEP 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | namespace nodepp { namespace process { struct NODE_INTERVAL { FILETIME ft; ULARGE_INTEGER time; }; } } 22 | namespace nodepp { namespace process { 23 | 24 | inline NODE_INTERVAL get_new_interval(){ 25 | NODE_INTERVAL interval; GetSystemTimeAsFileTime( &interval.ft ); 26 | interval.time.HighPart = interval.ft.dwHighDateTime; 27 | interval.time.LowPart = interval.ft.dwLowDateTime; 28 | return interval; 29 | } 30 | 31 | inline ulong micros(){ 32 | NODE_INTERVAL interval = get_new_interval(); 33 | return interval.time.QuadPart / 10; 34 | } 35 | 36 | inline ulong millis(){ 37 | NODE_INTERVAL interval = get_new_interval(); 38 | return interval.time.QuadPart / 10000; 39 | } 40 | 41 | inline ulong seconds(){ 42 | NODE_INTERVAL interval = get_new_interval(); 43 | return interval.time.QuadPart / 10000000; 44 | } 45 | 46 | }} 47 | 48 | /*────────────────────────────────────────────────────────────────────────────*/ 49 | 50 | namespace nodepp { namespace process { 51 | 52 | inline void delay( ulong time ){ ::Sleep( time ); } 53 | 54 | inline void yield(){ delay( TIMEOUT ); } 55 | 56 | inline ulong now(){ return millis(); } 57 | 58 | }} 59 | 60 | /*────────────────────────────────────────────────────────────────────────────*/ 61 | 62 | #endif 63 | 64 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /examples/32-HTTP-Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace nodepp; 9 | 10 | void onMain(){ 11 | 12 | auto server = http::server([=]( http_t cli ){ 13 | 14 | string_t dir = "www/index.html"; 15 | if( cli.path != "/" ) 16 | dir = path::join( "www", cli.path ); 17 | 18 | console::log( cli.path, cli.get_fd() ); 19 | 20 | if( !fs::exists_file(dir) ){ 21 | cli.write_header( 404, header_t({ 22 | { "content-type", "text/plain" } 23 | }) ); 24 | cli.write("Oops: 404 Error"); 25 | cli.close(); return; 26 | } 27 | 28 | auto str = fs::readable( dir ); 29 | 30 | if( cli.headers["Range"].empty() ){ 31 | 32 | cli.write_header( 200, header_t({ 33 | { "Content-Length", string::to_string(str.size()) }, 34 | // { "Cache-Control", "public, max-age=3600" }, 35 | { "Content-Type", path::mimetype(dir) } 36 | })); 37 | 38 | if(!regex::test(path::mimetype(dir),"audio|video",true) ) 39 | stream::pipe( str, cli ); 40 | 41 | } else { 42 | 43 | array_t range = regex::match_all(cli.headers["Range"],"\\d+",true); 44 | ulong rang[3]; rang[0] = string::to_ulong( range[0] ); 45 | rang[2] = min( rang[0]+CHUNK_MB(10), str.size() ); 46 | rang[1] = min( rang[0]+CHUNK_MB(10), str.size()-1 ); 47 | 48 | cli.write_header( 206, header_t({ 49 | { "Content-Range", string::format("bytes %lu-%lu/%lu",rang[0],rang[1],str.size()) }, 50 | { "Content-Type", path::mimetype(dir) }, 51 | { "Accept-Range", "bytes" } 52 | })); 53 | 54 | str.set_range( rang[0], rang[2] ); 55 | stream::pipe( str, cli ); 56 | 57 | } 58 | 59 | }); 60 | 61 | server.listen( "localhost", 8000, [=]( socket_t /*unused*/ ){ 62 | console::log("server started at http://localhost:8000"); 63 | }); 64 | 65 | } -------------------------------------------------------------------------------- /examples/34-HTTPS-Server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace nodepp; 9 | 10 | void onMain(){ 11 | 12 | ssl_t ssl; // ( "./ssl/cert.key", "./ssl/cert.crt" ); 13 | 14 | auto server = https::server([=]( https_t cli ){ 15 | 16 | string_t dir = "www/index.html"; 17 | if( cli.path.size() > 1 ) 18 | dir = path::join( "www", cli.path ); 19 | 20 | console::log( cli.path, cli.get_fd() ); 21 | 22 | if( !fs::exists_file(dir) ){ 23 | cli.write_header( 404, header_t({ 24 | { "content-type", "text/plain" } } 25 | )); 26 | cli.write("Oops: 404 Error"); 27 | cli.close(); return; 28 | } 29 | 30 | auto str = fs::readable( dir ); 31 | 32 | if( cli.headers["Range"].empty() ){ 33 | 34 | cli.write_header( 200, header_t({ 35 | { "Content-Length", string::to_string(str.size()) }, 36 | // { "Cache-Control", "public, max-age=3600" }, 37 | { "Content-Type", path::mimetype(dir) } 38 | })); 39 | 40 | if(!regex::test(path::mimetype(dir),"audio|video",true) ) 41 | stream::pipe( str, cli ); 42 | 43 | } else { 44 | 45 | array_t range = regex::match_all(cli.headers["Range"],"\\d+",true); 46 | ulong rang[3]; rang[0] = string::to_ulong( range[0] ); 47 | rang[2] = min( rang[0]+CHUNK_MB(10), str.size() ); 48 | rang[1] = min( rang[0]+CHUNK_MB(10), str.size()-1 ); 49 | 50 | cli.write_header( 206, header_t({ 51 | { "Content-Range", string::format("bytes %lu-%lu/%lu",rang[0],rang[1],str.size()) }, 52 | { "Content-Type", path::mimetype(dir) }, 53 | { "Accept-Range", "bytes" } 54 | })); 55 | 56 | str.set_range( rang[0], rang[2] ); 57 | stream::pipe( str, cli ); 58 | 59 | } 60 | 61 | }, &ssl ); 62 | 63 | server.listen( "localhost", 8000, [=]( ssocket_t /*unused*/ ){ 64 | console::log("server started at https://localhost:8000"); 65 | }); 66 | 67 | } -------------------------------------------------------------------------------- /include/nodepp/popen.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_POPEN 13 | #define NODEPP_POPEN 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | 19 | #include "fs.h" 20 | #include "worker.h" 21 | #include "initializer.h" 22 | #include "windows/popen.h" 23 | 24 | namespace nodepp { namespace popen { 25 | 26 | template< class... T > string_t await( const T&... args ){ 27 | string_t out; auto pid = type::bind( popen_t( args... ) ); 28 | pid->onData([&]( string_t chunk ){ out += chunk; }); 29 | worker::await([&](){ return pid->next(); }); 30 | return out; } 31 | 32 | template< class... T > popen_t async( const T&... args ){ 33 | auto pid = type::bind( popen_t( args... ) ); 34 | worker::add([=](){ return pid->next(); }); 35 | return *pid; } 36 | 37 | }} 38 | 39 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 40 | 41 | #include "fs.h" 42 | #include "initializer.h" 43 | #include "posix/popen.h" 44 | 45 | namespace nodepp { namespace popen { 46 | 47 | template< class... T > string_t await( const T&... args ){ 48 | string_t out; auto pid = type::bind( popen_t( args... ) ); 49 | pid->onData([&]( string_t chunk ){ out += chunk; }); 50 | process::await([&](){ return pid->next(); }); 51 | return out; } 52 | 53 | template< class... T > popen_t async( const T&... args ){ 54 | auto pid = type::bind( popen_t( args... ) ); 55 | process::foop([=](){ return pid->next(); }); 56 | return *pid; } 57 | 58 | }} 59 | 60 | #else 61 | #error "This OS Does not support popen.h" 62 | #endif 63 | 64 | /*────────────────────────────────────────────────────────────────────────────*/ 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /include/nodepp/posix/env.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_POSIX_ENV 13 | #define NODEPP_POSIX_ENV 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | namespace nodepp { namespace process { namespace env { 22 | 23 | inline int set( const string_t& name, const string_t& value ){ return setenv( name.c_str(), value.c_str(), 1 ); } 24 | 25 | inline string_t get( const string_t& name ){ return getenv( name.c_str() ); } 26 | 27 | inline int remove( const string_t& name ){ return unsetenv( name.c_str() ); } 28 | 29 | inline int init( const string_t& path ){ try { 30 | 31 | static regex_t reg( "^([^ =]+)[= \"]+([^\n#\"]+)" ); 32 | auto file = file_t( path, "r" ); 33 | 34 | while( !file.is_closed() ){ 35 | /*--------*/ reg.match_all( file.read_line() ); 36 | auto match = reg.get_memory (); 37 | /*--------*/ reg.clear_memory(); 38 | 39 | if ( match.size() != 2 ){ continue; } 40 | set( match[0], match[1] ); 41 | } 42 | 43 | } catch(...) { return -1; } return 1; } 44 | 45 | }}} 46 | 47 | /*────────────────────────────────────────────────────────────────────────────*/ 48 | 49 | namespace nodepp { namespace process { 50 | 51 | inline bool is_child(){ return !env::get("CHILD").empty(); } 52 | 53 | inline bool is_parent(){ return env::get("CHILD").empty(); } 54 | 55 | inline string_t shell(){ return env::get("SHELL"); } 56 | 57 | inline string_t home(){ return env::get("HOME"); } 58 | 59 | }} 60 | 61 | /*────────────────────────────────────────────────────────────────────────────*/ 62 | 63 | #endif 64 | 65 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /include/nodepp/console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_CONSOLE 13 | #define NODEPP_CONSOLE 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include "conio.h" 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | namespace nodepp { namespace console { 22 | 23 | template< class... T > 24 | int err( const T&... args ){ return conio::err(args...,"\n"); } 25 | 26 | template< class... T > 27 | int log( const T&... args ){ return conio::log(args...,"\n"); } 28 | 29 | template< class... T > 30 | int scan( const T&... args ){ return conio::scan( args... ); } 31 | 32 | template< class... T > 33 | int pout( const T&... args ){ return conio::log( args... ); } 34 | 35 | inline void wait(){ char x; conio::scan("%c",&x); } 36 | 37 | inline void clear(){ conio::clear(); } 38 | 39 | /*─······································································─*/ 40 | 41 | template< class... T > 42 | int warning( const T&... args ){ 43 | conio::warn("WARNING: "); 44 | return log( args... ); 45 | } 46 | 47 | template< class... T > 48 | int success( const T&... args ){ 49 | conio::done("SUCCESS: "); 50 | return log( args... ); 51 | } 52 | 53 | template< class... T > 54 | int error( const T&... args ){ 55 | conio::error("ERROR: "); 56 | return log( args... ); 57 | } 58 | 59 | template< class... T > 60 | int done( const T&... args ){ 61 | conio::done("DONE: "); 62 | return log( args... ); 63 | } 64 | 65 | template< class... T > 66 | int info( const T&... args ){ 67 | conio::info("INFO: "); 68 | return log( args... ); 69 | } 70 | 71 | }} 72 | 73 | /*────────────────────────────────────────────────────────────────────────────*/ 74 | 75 | #endif -------------------------------------------------------------------------------- /examples/38-WSS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace nodepp; 9 | 10 | void server(){ 11 | 12 | ssl_t ssl; //ssl_t ssl( "./ssl/cert.key", "./ssl/cert.crt" ); 13 | 14 | auto server = https::server([=]( https_t cli ){ 15 | 16 | cli.write_header( 200, header_t({ 17 | { "Content-Security-Policy", "*" } 18 | }) ); 19 | 20 | cli.write("Hello World!"); 21 | 22 | }, &ssl ); wss::server( server ); 23 | 24 | server.onConnect([=]( wss_t cli ){ 25 | 26 | auto cin = fs::std_input(); 27 | console::log("connected"); 28 | 29 | cin.onData([=]( string_t data ){ 30 | cli.write( data ); 31 | }); 32 | 33 | cli.onData([=]( string_t data ){ 34 | console::log( "serv:", data ); 35 | }); 36 | 37 | cli.onDrain([=](){ 38 | console::log("closed"); 39 | cin.close(); 40 | }); 41 | 42 | stream::pipe( cin ); 43 | 44 | }); 45 | 46 | server.listen( "localhost", 8000, [=]( ssocket_t server ){ 47 | console::log("server started at https://localhost:8000"); 48 | }); 49 | 50 | } 51 | 52 | void client() { 53 | 54 | ssl_t ssl; //ssl_t ssl( "./ssl/cert.key", "./ssl/cert.crt" ); 55 | 56 | auto client = wss::client( "wss://localhost:8000/", &ssl ); 57 | 58 | client.onConnect([=]( wss_t cli ){ 59 | 60 | auto cin = fs::std_input(); 61 | console::log("connected"); 62 | 63 | cli.onData([]( string_t chunk ){ 64 | console::log("cli:", chunk); 65 | }); 66 | 67 | cin.onData([=]( string_t data ){ 68 | cli.write( data ); 69 | }); 70 | 71 | cli.onDrain([=](){ 72 | console::log("closed"); 73 | cin.close(); 74 | }); 75 | 76 | stream::pipe( cin ); 77 | 78 | }); 79 | 80 | client.onError([=]( except_t err ){ 81 | console::log( "<>", err.data() ); 82 | }); 83 | 84 | } 85 | 86 | void onMain() { 87 | 88 | if( process::env::get("mode")=="client" ) 89 | { client(); } else { server(); } 90 | 91 | } 92 | 93 | // g++ -o main main.cpp -I./include ; ./main ?mode=client -------------------------------------------------------------------------------- /test/any.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace ANY { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | any initialization string", [](){ 18 | try { any_t mem = "hello world"; 19 | if ( !mem.has_value() )/*---------------*/{ throw 0; } 20 | if ( mem.as() != "hello world" ){ throw 0; } 21 | TEST_DONE(); 22 | } catch ( ... ) { TEST_FAIL(); } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | any initialization uint", [](){ 26 | try { any_t mem = type::cast(10); 27 | if ( !mem.has_value() ) { throw 0; } 28 | if ( mem.as() != 10 ){ throw 0; } 29 | TEST_DONE(); 30 | } catch ( ... ) { TEST_FAIL(); } 31 | }); 32 | 33 | TEST_ADD( test, "TEST 3 | any initialization float", [](){ 34 | try { any_t mem = type::cast(10); 35 | if ( !mem.has_value() )/*----*/{ throw 0; } 36 | if ( mem.as() != 10.0f ){ throw 0; } 37 | TEST_DONE(); 38 | } catch ( ... ) { TEST_FAIL(); } 39 | }); 40 | 41 | TEST_ADD( test, "TEST 4 | any initialization object", [](){ 42 | try { any_t mem = object_t({ { "var1", 10 } }); 43 | if ( !mem.has_value() )/*----------------------*/{ throw 0; } 44 | if ( mem.as()["var1"].as() != 10 ){ throw 0; } 45 | TEST_DONE(); 46 | } catch ( ... ) { TEST_FAIL(); } 47 | }); 48 | 49 | test.onClose.once([=](){ 50 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 51 | }); 52 | 53 | test.onDone([=](){ (*done)++; (*totl)++; }); 54 | test.onFail([=](){ (*err)++; (*totl)++; }); 55 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 56 | 57 | TEST_AWAIT( test ); 58 | 59 | } 60 | 61 | }} -------------------------------------------------------------------------------- /include/nodepp/posix/os.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_POSIX_OS 13 | #define NODEPP_POSIX_OS 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | #include 19 | 20 | /*────────────────────────────────────────────────────────────────────────────*/ 21 | 22 | namespace nodepp { namespace os { 23 | 24 | inline string_t hostname(){ char buff[UNBFF_SIZE]; return ::gethostname(buff,UNBFF_SIZE)==0 ? buff : nullptr; } 25 | 26 | /*─······································································─*/ 27 | 28 | inline string_t cwd(){ char buff[UNBFF_SIZE]; return ::getcwd(buff,UNBFF_SIZE)==nullptr ? nullptr : buff; } 29 | 30 | /*─······································································─*/ 31 | 32 | inline uint cpus(){ return ::sysconf( _SC_NPROCESSORS_ONLN ); } 33 | 34 | /*─······································································─*/ 35 | 36 | inline int exec( string_t cmd ){ return ::system( cmd.get() ); } 37 | 38 | inline int call( string_t cmd ){ return ::system( cmd.get() ); } 39 | 40 | /*─······································································─*/ 41 | 42 | inline string_t user(){ return ::getlogin(); } 43 | 44 | /*─······································································─*/ 45 | 46 | inline string_t tmp(){ return "/tmp"; } 47 | 48 | /*─······································································─*/ 49 | 50 | inline uint pid(){ return ::getpid(); } 51 | 52 | /*─······································································─*/ 53 | 54 | inline uint error(){ return errno; } 55 | 56 | }} 57 | 58 | /*────────────────────────────────────────────────────────────────────────────*/ 59 | 60 | #endif 61 | 62 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /test/observer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace OBSERVER { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | observer initialization", [](){ 18 | try { 19 | observer_t obj ({ 20 | { "var1", 10 }, 21 | { "var2", 20 }, 22 | { "var3", 30 }, 23 | }); 24 | if ( obj.size() != 3 ){ throw 0; } 25 | TEST_DONE(); 26 | } catch ( ... ) { TEST_FAIL(); } 27 | }); 28 | 29 | TEST_ADD( test, "TEST 2 | observer get", [](){ 30 | try { 31 | observer_t obj ({ 32 | { "var1", 10 }, 33 | { "var2", 20 }, 34 | { "var3", 30 }, 35 | }); 36 | if ( obj.get("var2").as() != 20 ){ throw 0; } 37 | TEST_DONE(); 38 | } catch ( ... ) { TEST_FAIL(); } 39 | }); 40 | 41 | TEST_ADD( test, "TEST 2 | observer set", [](){ 42 | try { 43 | 44 | ptr_t val = new int(0); 45 | 46 | observer_t obj ({ 47 | { "var1", 10 }, 48 | { "var2", 20 }, 49 | { "var3", 30 }, 50 | }); 51 | 52 | obj.once( "var2", [=]( any_t a, any_t b ){ 53 | *val = b.as(); 54 | }); obj.set("var2",30); 55 | 56 | if ( *val != 30 ){ throw 0; } 57 | TEST_DONE(); 58 | } catch ( ... ) { TEST_FAIL(); } 59 | }); 60 | 61 | test.onClose.once([=](){ 62 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 63 | }); 64 | 65 | test.onDone([=](){ (*done)++; (*totl)++; }); 66 | test.onFail([=](){ (*err)++; (*totl)++; }); 67 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 68 | 69 | TEST_AWAIT( test ); 70 | 71 | } 72 | 73 | }} -------------------------------------------------------------------------------- /test/regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace REGEX { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | regex search", [](){ 18 | try { auto out = regex::search_all( "hello 123 world!", "\\w+" ); 19 | if ( out.size() != 3 ){ throw 0; } 20 | TEST_DONE(); 21 | } catch ( ... ) { TEST_FAIL(); } 22 | }); 23 | 24 | TEST_ADD( test, "TEST 2 | regex match", [](){ 25 | try { auto out = regex::match_all( "hello 123 world!", "[^ ]+" ); 26 | if ( out.size() != 3 ){ throw 0; } 27 | if ( out[0] != "hello" ){ throw 0; } 28 | if ( out[1] != "123" ){ throw 0; } 29 | if ( out[2] != "world!"){ throw 0; } 30 | TEST_DONE(); 31 | } catch ( ... ) { TEST_FAIL(); } 32 | }); 33 | 34 | TEST_ADD( test, "TEST 3 | regex memory", [](){ 35 | try { auto out = regex::get_memory( "hello 123 world!", "([^ ]+)" ); 36 | if ( out.size() != 3 ){ throw 0; } 37 | if ( out[0] != "hello" ){ throw 0; } 38 | if ( out[1] != "123" ){ throw 0; } 39 | if ( out[2] != "world!"){ throw 0; } 40 | TEST_DONE(); 41 | } catch ( ... ) { TEST_FAIL(); } 42 | }); 43 | 44 | TEST_ADD( test, "TEST 4 | regex format", [](){ 45 | try { auto out = regex::format( "${0} ${1}", "hello", "world" ); 46 | if ( out != "hello world" ){ throw 0; } 47 | TEST_DONE(); 48 | } catch ( ... ) { TEST_FAIL(); } 49 | }); 50 | 51 | test.onClose.once([=](){ 52 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 53 | }); 54 | 55 | test.onDone([=](){ (*done)++; (*totl)++; }); 56 | test.onFail([=](){ (*err)++; (*totl)++; }); 57 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 58 | 59 | TEST_AWAIT( test ); 60 | 61 | } 62 | 63 | }} -------------------------------------------------------------------------------- /test/variant.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace VARIANT { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | variant initialization string", [](){ 18 | try { variant_t mem = "hello world"; 19 | if ( !mem.has_value() )/*---------------*/{ throw 0; } 20 | if ( mem.as() != "hello world" ){ throw 0; } 21 | TEST_DONE(); 22 | } catch ( ... ) { TEST_FAIL(); } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | variant initialization uint", [](){ 26 | try { variant_t mem = type::cast(10); 27 | if ( !mem.has_value() ) { throw 0; } 28 | if ( mem.as() != 10 ){ throw 0; } 29 | TEST_DONE(); 30 | } catch ( ... ) { TEST_FAIL(); } 31 | }); 32 | 33 | TEST_ADD( test, "TEST 3 | variant initialization float", [](){ 34 | try { variant_t mem = type::cast(10); 35 | if ( !mem.has_value() )/*----*/{ throw 0; } 36 | if ( mem.as() != 10.0f ){ throw 0; } 37 | TEST_DONE(); 38 | } catch ( ... ) { TEST_FAIL(); } 39 | }); 40 | 41 | TEST_ADD( test, "TEST 4 | variant error handling", [](){ 42 | try { variant_t mem = object_t({ { "var1", 10 } }); 43 | if ( !mem.has_value() )/*----------------------*/{ throw 0; } 44 | if ( mem.as()["var1"].as() != 10 ){ throw 0; } 45 | TEST_FAIL(); 46 | } catch ( ... ) { TEST_DONE(); } 47 | }); 48 | 49 | test.onClose.once([=](){ 50 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 51 | }); 52 | 53 | test.onDone([=](){ (*done)++; (*totl)++; }); 54 | test.onFail([=](){ (*err)++; (*totl)++; }); 55 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 56 | 57 | TEST_AWAIT( test ); 58 | 59 | } 60 | 61 | }} -------------------------------------------------------------------------------- /include/nodepp/windows/env.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_WINDOWS_ENV 13 | #define NODEPP_WINDOWS_ENV 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | namespace nodepp { namespace process { namespace env { 22 | 23 | inline int set( const string_t& name, const string_t& value ){ return SetEnvironmentVariableA( name.c_str(), value.c_str() ); } 24 | 25 | inline int remove( const string_t& name ){ return SetEnvironmentVariableA( name.c_str(), nullptr ); } 26 | 27 | inline string_t get( const string_t& name ){ ptr_t buffer ( UNBFF_SIZE ); 28 | auto x = GetEnvironmentVariableA( name.c_str(), &buffer, buffer.size() ); 29 | return string_t( &buffer, (ulong) x ); 30 | } 31 | 32 | inline int init( const string_t& path ){ try { 33 | 34 | static regex_t reg( "^([^ =]+)[= \"]+([^\n#\"]+)" ); 35 | auto file = file_t( path, "r" ); 36 | 37 | while( !file.is_closed() ){ 38 | /*--------*/ reg.match_all( file.read_line() ); 39 | auto match = reg.get_memory (); 40 | /*--------*/ reg.clear_memory(); 41 | 42 | if ( match.size() != 2 ){ continue; } 43 | set( match[0], match[1] ); 44 | } 45 | 46 | } catch(...) { return -1; } return 1; } 47 | 48 | }}} 49 | 50 | /*────────────────────────────────────────────────────────────────────────────*/ 51 | 52 | namespace nodepp { namespace process { 53 | 54 | inline bool is_child(){ return !env::get("CHILD").empty(); } 55 | 56 | inline bool is_parent(){ return env::get("CHILD").empty(); } 57 | 58 | inline string_t home(){ return env::get("USERPROFILE"); } 59 | 60 | inline string_t shell(){ return env::get("COMSPEC"); } 61 | 62 | }} 63 | 64 | /*────────────────────────────────────────────────────────────────────────────*/ 65 | 66 | #endif 67 | 68 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | #include "dns.cpp" 7 | #include "url.cpp" 8 | #include "any.cpp" 9 | #include "ptr.cpp" 10 | #include "map.cpp" 11 | #include "json.cpp" 12 | #include "task.cpp" 13 | #include "path.cpp" 14 | #include "loop.cpp" 15 | #include "wait.cpp" 16 | #include "file.cpp" 17 | #include "http.cpp" 18 | #include "tuple.cpp" 19 | #include "worker.cpp" 20 | #include "cookie.cpp" 21 | #include "event.cpp" 22 | #include "query.cpp" 23 | #include "array.cpp" 24 | #include "queue.cpp" 25 | #include "regex.cpp" 26 | #include "atomic.cpp" 27 | #include "string.cpp" 28 | #include "variant.cpp" 29 | #include "promise.cpp" 30 | #include "function.cpp" 31 | #include "observer.cpp" 32 | #include "optional.cpp" 33 | #include "expected.cpp" 34 | 35 | void onMain(){ 36 | 37 | TEST::DNS ::TEST_RUNNER(); conio::log("\n---\n"); 38 | TEST::URL ::TEST_RUNNER(); conio::log("\n---\n"); 39 | TEST::ANY ::TEST_RUNNER(); conio::log("\n---\n"); 40 | TEST::PTR ::TEST_RUNNER(); conio::log("\n---\n"); 41 | TEST::MAP ::TEST_RUNNER(); conio::log("\n---\n"); 42 | TEST::TASK ::TEST_RUNNER(); conio::log("\n---\n"); 43 | TEST::PATH ::TEST_RUNNER(); conio::log("\n---\n"); 44 | TEST::LOOP ::TEST_RUNNER(); conio::log("\n---\n"); 45 | TEST::WAIT ::TEST_RUNNER(); conio::log("\n---\n"); 46 | TEST::FILE ::TEST_RUNNER(); conio::log("\n---\n"); 47 | TEST::HTTP ::TEST_RUNNER(); conio::log("\n---\n"); 48 | TEST::TUPLE ::TEST_RUNNER(); conio::log("\n---\n"); 49 | TEST::COOKIE ::TEST_RUNNER(); conio::log("\n---\n"); 50 | TEST::EVENT ::TEST_RUNNER(); conio::log("\n---\n"); 51 | TEST::QUERY ::TEST_RUNNER(); conio::log("\n---\n"); 52 | TEST::JSON ::TEST_RUNNER(); conio::log("\n---\n"); 53 | TEST::ARRAY ::TEST_RUNNER(); conio::log("\n---\n"); 54 | TEST::WORKER ::TEST_RUNNER(); conio::log("\n---\n"); 55 | TEST::QUEUE ::TEST_RUNNER(); conio::log("\n---\n"); 56 | TEST::REGEX ::TEST_RUNNER(); conio::log("\n---\n"); 57 | TEST::STRING ::TEST_RUNNER(); conio::log("\n---\n"); 58 | TEST::ATOMIC ::TEST_RUNNER(); conio::log("\n---\n"); 59 | TEST::VARIANT ::TEST_RUNNER(); conio::log("\n---\n"); 60 | TEST::PROMISE ::TEST_RUNNER(); conio::log("\n---\n"); 61 | TEST::FUNCTION::TEST_RUNNER(); conio::log("\n---\n"); 62 | TEST::OBSERVER::TEST_RUNNER(); conio::log("\n---\n"); 63 | TEST::EXPECTED::TEST_RUNNER(); conio::log("\n---\n"); 64 | TEST::OPTION ::TEST_RUNNER(); conio::log("\n---\n"); 65 | 66 | } -------------------------------------------------------------------------------- /include/nodepp/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_VARIANT 13 | #define NODEPP_VARIANT 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include "any.h" 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | namespace nodepp { template< class... Types > class variant_t : public any_t { 22 | public: 23 | 24 | template< class T > 25 | variant_t( const T& V ) : any_t(V), idx( new int( is_valid(V) ) ) {} 26 | 27 | variant_t( const char* V ) : any_t( string::to_string(V) ), 28 | idx( new int( is_valid( string::to_string(V) ) ) ) {} 29 | 30 | variant_t() : any_t(), idx( new int(-1) ) {} 31 | 32 | virtual ~variant_t() noexcept {} 33 | 34 | /*─······································································─*/ 35 | 36 | template< class T > 37 | void set( const T& f ) { idx = is_valid( f ); any_t::set( f ); } 38 | 39 | template< class T > 40 | T get() const noexcept { return any_t::get(); } 41 | 42 | template< class T > 43 | T as() const noexcept { return any_t::as(); } 44 | 45 | protected: 46 | 47 | template< class T > 48 | int is_valid( T /*unused*/ ) { 49 | int idx = get_index::value; 50 | if( idx > (int) sizeof...(Types) ){ 51 | throw except_t("invalid data type"); 52 | } return idx; 53 | } 54 | 55 | /*─······································································─*/ 56 | 57 | template< class T, class... Us > struct get_index { 58 | static constexpr int value = 1; 59 | }; 60 | 61 | template< class T, class... Us > struct get_index { 62 | static constexpr int value = 0; 63 | }; 64 | 65 | template< class T, class U, class... Us > struct get_index { 66 | static constexpr int value = 1 + get_index::value; 67 | }; 68 | 69 | /*─······································································─*/ 70 | 71 | ptr_t idx; 72 | 73 | };} 74 | 75 | /*────────────────────────────────────────────────────────────────────────────*/ 76 | 77 | #endif -------------------------------------------------------------------------------- /include/nodepp/coroutine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_COROUTINE 13 | #define NODEPP_COROUTINE 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { struct generator_t { protected: 18 | ulong _time_ = 0; int _state_= 0; 19 | }; } 20 | 21 | /*────────────────────────────────────────────────────────────────────────────*/ 22 | 23 | namespace nodepp { class coroutine_t { 24 | private: 25 | 26 | using T = function_t; 27 | 28 | protected: 29 | 30 | struct NODE { 31 | T callback; 32 | ulong time=0; 33 | int state =0; 34 | bool alive=1; 35 | }; ptr_t obj; 36 | 37 | public: 38 | 39 | coroutine_t( T callback ) : obj( new NODE() ) { obj->callback = callback; } 40 | 41 | coroutine_t() : obj( new NODE() ) { obj->alive = 0; } 42 | 43 | virtual ~coroutine_t() noexcept {} 44 | 45 | /*─······································································─*/ 46 | 47 | void off() const noexcept { obj->alive = 0; obj->callback.free(); } 48 | 49 | void set_state( int value ) const noexcept { obj->state = value; } 50 | 51 | int get_state() const noexcept { return obj->state; } 52 | 53 | void free() const noexcept { off(); } 54 | 55 | /*─······································································─*/ 56 | 57 | bool is_closed() const noexcept { return !is_available(); } 58 | 59 | bool is_available() const noexcept { return obj->alive; } 60 | 61 | /*─······································································─*/ 62 | 63 | coEmit() const { return next(); } 64 | 65 | int next() const { 66 | if ( !obj->alive ){ return -1; } 67 | return obj->callback( obj->state, obj->time ); 68 | } 69 | 70 | }; } 71 | 72 | /*────────────────────────────────────────────────────────────────────────────*/ 73 | 74 | namespace nodepp { namespace coroutine { 75 | inline coroutine_t add( function_t callback ) { 76 | return coroutine_t( callback ); 77 | } 78 | }} 79 | 80 | /*────────────────────────────────────────────────────────────────────────────*/ 81 | 82 | #endif -------------------------------------------------------------------------------- /examples/0-Test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace nodepp; 5 | 6 | namespace TEST { namespace CONSOLE { 7 | 8 | void TEST_RUNNER(){ 9 | ptr_t totl = new uint(0); 10 | ptr_t done = new uint(0); 11 | ptr_t err = new uint(0); 12 | ptr_t skp = new uint(0); 13 | 14 | auto test = TEST_CREATE(); 15 | 16 | TEST_ADD( test, "TEST 1 | console log ", [](){ 17 | try { 18 | conio::log("-> "); console::log("Hello World!"); 19 | TEST_DONE(); 20 | } catch ( ... ) { 21 | TEST_FAIL(); 22 | } 23 | }); 24 | 25 | TEST_ADD( test, "TEST 2 | console info ", [](){ 26 | try { 27 | conio::log("-> "); console::info("Hello World!"); 28 | TEST_DONE(); 29 | } catch ( ... ) { 30 | TEST_FAIL(); 31 | } 32 | }); 33 | 34 | TEST_ADD( test, "TEST 3 | console done ", [](){ 35 | try { 36 | conio::log("-> "); console::done("Hello World!"); 37 | TEST_DONE(); 38 | } catch ( ... ) { 39 | TEST_FAIL(); 40 | } 41 | }); 42 | 43 | TEST_ADD( test, "TEST 4 | console error ", [](){ 44 | try { 45 | conio::log("-> "); console::error("Hello World!"); 46 | TEST_DONE(); 47 | } catch ( ... ) { 48 | TEST_FAIL(); 49 | } 50 | }); 51 | 52 | TEST_ADD( test, "TEST 5 | console success ", [](){ 53 | try { 54 | conio::log("-> "); console::success("Hello World!"); 55 | TEST_DONE(); 56 | } catch ( ... ) { 57 | TEST_FAIL(); 58 | } 59 | }); 60 | 61 | TEST_ADD( test, "TEST 6 | console warning ", [](){ 62 | try { 63 | conio::log("-> "); console::warning("Hello World!"); 64 | TEST_DONE(); 65 | } catch ( ... ) { 66 | TEST_FAIL(); 67 | } 68 | }); 69 | 70 | test.onClose.once([=](){ 71 | console::log(":> RESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 72 | }); 73 | 74 | test.onDone([=](){ (*done)++; (*totl)++; }); 75 | test.onFail([=](){ (*err)++; (*totl)++; }); 76 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 77 | 78 | TEST_AWAIT( test ); 79 | 80 | } 81 | 82 | }} 83 | 84 | void onMain(){ TEST::CONSOLE::TEST_RUNNER(); } -------------------------------------------------------------------------------- /include/nodepp/except.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_EXCEPT 13 | #define NODEPP_EXCEPT 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { class except_t { 18 | protected: 19 | 20 | struct NODE { 21 | void *ev = nullptr; 22 | string_t msg; 23 | }; ptr_t obj; 24 | 25 | public: 26 | 27 | virtual ~except_t() noexcept { 28 | if( obj->ev == nullptr ){ return; } 29 | process::onSIGERROR.off( obj->ev ); 30 | } 31 | 32 | except_t() noexcept : obj( new NODE() ) {} 33 | 34 | /*─······································································─*/ 35 | 36 | template< class T, class = typename type::enable_if::value,T>::type > 37 | except_t( const T& except_type ) noexcept : obj(new NODE()) { 38 | obj->msg = except_type.what(); auto inp = type::bind( this ); 39 | obj->ev = process::onSIGERROR.once([=](int){ inp->print(); }); 40 | } 41 | 42 | /*─······································································─*/ 43 | 44 | template< class... T > 45 | except_t( const T&... msg ) noexcept : obj(new NODE()) { 46 | obj->msg = string::join( " ", msg... ); auto inp = type::bind( this ); 47 | obj->ev = process::onSIGERROR.once([=](int){ inp->print(); }); 48 | } 49 | 50 | /*─······································································─*/ 51 | 52 | except_t( const string_t& msg ) noexcept : obj(new NODE()) { 53 | obj->msg = msg; auto inp = type::bind( this ); 54 | obj->ev = process::onSIGERROR.once([=](int){ inp->print(); }); 55 | } 56 | 57 | /*─······································································─*/ 58 | 59 | void print() const noexcept { console::error(obj->msg); } 60 | bool empty() const noexcept { return obj->msg.empty(); } 61 | const char* what() const noexcept { return obj->msg.c_str(); } 62 | operator char*() const noexcept { return (char*)what(); } 63 | string_t data() const noexcept { return obj->msg; } 64 | string_t value() const noexcept { return obj->msg; } 65 | 66 | };} 67 | 68 | /*────────────────────────────────────────────────────────────────────────────*/ 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /test/task.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace TASK { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | async task testing", [](){ 18 | try { ptr_t x = new int(0); 19 | ptr_t y = new int(3); 20 | 21 | process::add( coroutine::add( COROUTINE(){ 22 | coBegin 23 | 24 | while( *y>0 ){ *x += 10; *y-=1; coNext; } 25 | 26 | coFinish 27 | })); 28 | 29 | while( *y!=0 ){ process::next(); } 30 | if( *x != 30 ){ TEST_FAIL(); } 31 | TEST_DONE(); 32 | } catch ( ... ) { TEST_FAIL(); } 33 | }); 34 | 35 | TEST_ADD( test, "TEST 2 | sync task testing", [](){ 36 | try { ptr_t x = new int(0); 37 | ptr_t y = new int(3); 38 | 39 | process::await( coroutine::add( COROUTINE(){ 40 | coBegin 41 | 42 | while( *y>0 ){ *x += 10; *y-=1; coNext; } 43 | 44 | coFinish 45 | })); 46 | 47 | if( *x != 30 ){ TEST_FAIL(); } 48 | TEST_DONE(); 49 | } catch ( ... ) { TEST_FAIL(); } 50 | }); 51 | 52 | TEST_ADD( test, "TEST 3 | task resolver testing", [](){ 53 | try { ptr_t x = new int(0); 54 | ptr_t y = new int(3); 55 | 56 | promise::resolve( coroutine::add( COROUTINE(){ 57 | coBegin 58 | 59 | while( *y>0 ){ *x += 10; *y-=1; coNext; } 60 | 61 | coFinish 62 | })).emit(); 63 | 64 | while( *y!=0 ){ process::next(); } 65 | if( *x != 30 ){ TEST_FAIL(); } 66 | TEST_DONE(); 67 | } catch ( ... ) { TEST_FAIL(); } 68 | }); 69 | 70 | test.onClose.once([=](){ 71 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 72 | }); 73 | 74 | test.onDone([=](){ (*done)++; (*totl)++; }); 75 | test.onFail([=](){ (*err)++; (*totl)++; }); 76 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 77 | 78 | TEST_AWAIT( test ); 79 | 80 | } 81 | 82 | }} -------------------------------------------------------------------------------- /include/nodepp/function.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_FUNCTION 13 | #define NODEPP_FUNCTION 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { template< class V, class... T > class function_t { 18 | public: 19 | 20 | template< class F > 21 | function_t( F f ) : func_ptr( new func_impl(f) ) {} 22 | 23 | function_t( null_t ) noexcept : func_ptr(nullptr) {} 24 | 25 | function_t() noexcept : func_ptr(nullptr) {} 26 | 27 | virtual ~function_t() noexcept {} 28 | 29 | /*─······································································─*/ 30 | 31 | bool has_value() const noexcept { return func_ptr.has_value(); } 32 | ulong count() const noexcept { return func_ptr.count(); } 33 | bool empty() const noexcept { return func_ptr.null (); } 34 | bool null() const noexcept { return func_ptr.null (); } 35 | void free() const noexcept { /*--*/ func_ptr.free (); } 36 | 37 | /*─······································································─*/ 38 | 39 | explicit operator bool(void) const noexcept { return func_ptr.null(); } 40 | 41 | V operator()( const T&... arg ) const /*----*/ { return emit( arg... ); } 42 | 43 | V emit( const T&... arg ) const { 44 | if( !has_value() ){ return V(); } 45 | return func_ptr->invoke( arg... ); 46 | } 47 | 48 | private: 49 | 50 | class func_base { public: 51 | virtual ~func_base() { /*-----------------*/ } 52 | virtual V invoke( const T&... arg ) const = 0; 53 | }; 54 | 55 | /*─······································································─*/ 56 | 57 | template< class F > 58 | class func_impl : public func_base { 59 | 60 | public: 61 | 62 | func_impl( const F& f ) : func(f) { /*------------------------*/ } 63 | virtual V invoke( const T&... arg ) const { return func(arg...); } 64 | 65 | private: 66 | F func; 67 | }; 68 | 69 | /*─······································································─*/ 70 | 71 | ptr_t func_ptr; 72 | 73 | };} 74 | 75 | /*────────────────────────────────────────────────────────────────────────────*/ 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /include/nodepp/stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_STREAM 13 | #define NODEPP_STREAM 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include "file.h" 18 | #include "event.h" 19 | #include "generator.h" 20 | 21 | /*────────────────────────────────────────────────────────────────────────────*/ 22 | 23 | namespace nodepp { namespace stream { 24 | 25 | template< class T > 26 | void unpipe( const T& input ){ input.stop(); input.onUnpipe.emit(); } 27 | 28 | /*─······································································─*/ 29 | 30 | template< class... T > 31 | void duplex( const T&... inp ){ generator::stream::duplex arg; 32 | process::foop( arg, inp... ); 33 | } 34 | 35 | /*─······································································─*/ 36 | 37 | template< class... T > 38 | void until( const T&... inp ){ generator::stream::until arg; 39 | process::foop( arg, inp... ); 40 | } 41 | 42 | /*─······································································─*/ 43 | 44 | template< class... T > 45 | void pipe( const T&... inp ){ generator::stream::pipe arg; 46 | process::foop( arg, inp... ); 47 | } 48 | 49 | /*─······································································─*/ 50 | 51 | template< class... T > 52 | void line( const T&... inp ){ generator::stream::line arg; 53 | process::foop( arg, inp... ); 54 | } 55 | 56 | /*─······································································─*/ 57 | 58 | template< class T, class V > 59 | ulong await( const T& fa, const V& fb ){ 60 | ulong out; /*-----------*/ generator::stream::pipe arg; 61 | fa.onData([&]( string_t data ){ out += data.size(); }); 62 | process::await( arg, fa, fb ); 63 | return out; } 64 | 65 | template< class T > 66 | string_t await( const T& fp ){ 67 | queue_t out; generator::stream::pipe arg; 68 | fp.onData([&]( string_t data ){ out.push(data); }); 69 | process::await( arg, fp ); 70 | return array_t( out.data() ).join(""); } 71 | 72 | }} 73 | 74 | /*────────────────────────────────────────────────────────────────────────────*/ 75 | 76 | #endif -------------------------------------------------------------------------------- /include/nodepp/loop.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_LOOP 13 | #define NODEPP_LOOP 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { class loop_t : public generator_t { 18 | private: 19 | 20 | using NODE_CLB = function_t; 21 | struct waiter { bool blk; bool out; }; 22 | 23 | protected: 24 | 25 | struct NODE { 26 | queue_t queue; 27 | }; ptr_t obj; 28 | 29 | public: 30 | 31 | virtual ~loop_t() noexcept { /*-----*/ } 32 | 33 | loop_t() noexcept : obj( new NODE() ) {} 34 | 35 | /*─······································································─*/ 36 | 37 | void clear() const noexcept { /*--*/ obj->queue.clear(); } 38 | 39 | ulong size() const noexcept { return obj->queue.size (); } 40 | 41 | bool empty() const noexcept { return obj->queue.empty(); } 42 | 43 | /*─······································································─*/ 44 | 45 | inline int next() noexcept { 46 | coBegin 47 | 48 | if( obj->queue.empty() ) /*-*/ { coEnd; } do { 49 | if( obj->queue.get()==nullptr ){ coEnd; } 50 | 51 | auto x = obj->queue.get(); 52 | auto y = x->data(); 53 | 54 | switch( y ){ 55 | case -1: obj->queue.erase(x); break; 56 | case 1: obj->queue.next(); break; 57 | default: /*--------------*/ break; 58 | } 59 | 60 | return y; } while(0); 61 | 62 | coFinish } 63 | 64 | /*─······································································─*/ 65 | 66 | template< class T, class... V > 67 | inline void* add( T cb, const V&... arg ) const noexcept { 68 | 69 | ptr_t tsk = new waiter(); /*----------*/ 70 | auto clb=type::bind(cb); tsk->blk=0; tsk->out=1; 71 | 72 | obj->queue.push([=](){ 73 | if( tsk->out==0 ){ return -1; } 74 | if( tsk->blk==1 ){ return 1; } 75 | tsk->blk =1; int rs=(*clb)( arg... ); 76 | if( clb.null() ){ return -1; } 77 | tsk->blk =0; return !tsk->out?-1:rs; 78 | }); 79 | 80 | return (void*) &tsk->out; 81 | } 82 | 83 | };} 84 | 85 | /*────────────────────────────────────────────────────────────────────────────*/ 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/nodepp/tuple.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_TUPLE 13 | #define NODEPP_TUPLE 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | template class tuple_t {}; 22 | 23 | template 24 | class tuple_t : public tuple_t { 25 | public: tuple_t() noexcept {} virtual ~tuple_t() noexcept {} 26 | tuple_t( const Head& head, const Tail&... tail ) noexcept : tuple_t(tail...), head_(new Head(head)) {} 27 | tuple_t tail() const noexcept { return *this; } 28 | Head& head() const noexcept { return *head_; } 29 | private: 30 | ptr_t head_; 31 | }; 32 | 33 | /*────────────────────────────────────────────────────────────────────────────*/ 34 | 35 | namespace tuple { 36 | 37 | template 38 | struct tuple_element { using type = typename tuple_element< Index - 1 , Tail...>::type; }; 39 | 40 | template 41 | struct tuple_element<0, Head, Tail...> { using type = Head; }; 42 | 43 | /*─······································································─*/ 44 | 45 | template 46 | struct get_helper { 47 | static typename tuple_element::type& get(const tuple_t& tuple) { 48 | return get_helper::get(tuple.tail()); 49 | } 50 | }; 51 | 52 | template 53 | struct get_helper<0, Head, Tail...> { 54 | static Head& get(const tuple_t& tuple) { 55 | return tuple.head(); 56 | } 57 | }; 58 | 59 | /*─······································································─*/ 60 | 61 | template 62 | typename tuple_element::type& get(const tuple_t& tuple) { 63 | static_assert( Index < sizeof...(Types), "Index out of bounds in tuple get" ); 64 | return get_helper::get(tuple); 65 | } 66 | 67 | } 68 | 69 | /*────────────────────────────────────────────────────────────────────────────*/ 70 | 71 | } 72 | 73 | #endif -------------------------------------------------------------------------------- /include/nodepp/windows/os.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_WINDOWS_OS 13 | #define NODEPP_WINDOWS_OS 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | 19 | /*────────────────────────────────────────────────────────────────────────────*/ 20 | 21 | namespace nodepp { namespace os { 22 | 23 | inline string_t hostname(){ 24 | char buffer[UNBFF_SIZE]; DWORD bufferSize = UNBFF_SIZE; 25 | GetComputerNameA(buffer,&bufferSize); return string_t( buffer, bufferSize ); 26 | } 27 | 28 | /*─······································································─*/ 29 | 30 | inline string_t user(){ 31 | char buffer[UNBFF_SIZE]; DWORD bufferSize = UNBFF_SIZE; 32 | GetUserNameA(buffer, &bufferSize); return string_t( buffer, bufferSize ); 33 | } 34 | 35 | /*─······································································─*/ 36 | 37 | inline string_t cwd(){ char buffer[ UNBFF_SIZE ]; 38 | DWORD length = GetCurrentDirectoryA( UNBFF_SIZE, buffer ); 39 | return string_t( buffer, length ); 40 | } 41 | 42 | /*─······································································─*/ 43 | 44 | inline uint cpus(){ 45 | SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); 46 | return sysInfo.dwNumberOfProcessors; 47 | } 48 | 49 | /*─······································································─*/ 50 | 51 | inline string_t tmp(){ string_t tmp (MAX_PATH); 52 | GetTempPathA( MAX_PATH, tmp.data() ); 53 | return tmp; 54 | } 55 | 56 | /*─······································································─*/ 57 | 58 | inline int exec( string_t cmd ){ return ::system( cmd.get() ); } 59 | 60 | inline int call( string_t cmd ){ return ::system( cmd.get() ); } 61 | 62 | /*─······································································─*/ 63 | 64 | inline uint pid(){ return GetCurrentProcessId(); } 65 | 66 | /*─······································································─*/ 67 | 68 | inline DWORD error(){ return GetLastError(); } 69 | 70 | }} 71 | 72 | /*────────────────────────────────────────────────────────────────────────────*/ 73 | 74 | #endif 75 | 76 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /include/nodepp/cluster.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_CLUSTER 13 | #define NODEPP_CLUSTER 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #if _KERNEL_ == NODEPP_KERNEL_WINDOWS 18 | 19 | #include "fs.h" 20 | #include "worker.h" 21 | #include "initializer.h" 22 | #include "windows/cluster.h" 23 | 24 | namespace nodepp { namespace cluster { 25 | 26 | template< class... T > cluster_t async( const T&... args ){ 27 | auto pid = type::bind( cluster_t(args...) ); 28 | if( process::is_parent() ) { 29 | worker::add([=](){ return pid->next(); }); 30 | } return *pid; } 31 | 32 | template< class... T > cluster_t add( const T&... args ){ 33 | return async( args... ); } 34 | 35 | template< class... T > int await( const T&... args ){ 36 | auto pid = type::bind( cluster_t(args...) ); 37 | if( process::is_parent() ) { 38 | return worker::await([=](){ return pid->next(); }); 39 | } return -1; } 40 | 41 | inline bool is_child(){ return !process::env::get("CHILD").empty(); } 42 | 43 | inline bool is_parent(){ return process::env::get("CHILD").empty(); } 44 | 45 | }} 46 | 47 | 48 | #elif _KERNEL_ == NODEPP_KERNEL_POSIX 49 | 50 | #include "fs.h" 51 | #include "initializer.h" 52 | #include "posix/cluster.h" 53 | 54 | namespace nodepp { namespace cluster { 55 | 56 | template< class... T > cluster_t async( const T&... args ){ 57 | auto pid = type::bind( cluster_t(args...) ); 58 | if( process::is_parent() ) { 59 | process::foop([=](){ return pid->next(); }); 60 | } return *pid; } 61 | 62 | template< class... T > cluster_t add( const T&... args ){ 63 | return async( args... ); } 64 | 65 | template< class... T > int await( const T&... args ){ 66 | auto pid = type::bind( cluster_t(args...) ); 67 | if( process::is_parent() ) { 68 | return process::await([=](){ return pid->next(); }); 69 | } return -1; } 70 | 71 | inline bool is_child(){ return !process::env::get("CHILD").empty(); } 72 | 73 | inline bool is_parent(){ return process::env::get("CHILD").empty(); } 74 | 75 | }} 76 | 77 | #else 78 | #error "This OS Does not support cluster.h" 79 | #endif 80 | 81 | /*────────────────────────────────────────────────────────────────────────────*/ 82 | 83 | #endif -------------------------------------------------------------------------------- /include/nodepp/signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_SIGNAL 13 | #define NODEPP_SIGNAL 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include 18 | #include "event.h" 19 | 20 | /*────────────────────────────────────────────────────────────────────────────*/ 21 | 22 | namespace nodepp { namespace process { 23 | 24 | event_t onSIGERROR; event_t<> onSIGEXIT; 25 | 26 | namespace signal { 27 | 28 | inline void start() { 29 | ::signal( SIGFPE, []( int param ){ onSIGERROR.emit(SIGFPE ); conio::error("SIGFPE: "); console::log("Floating Point Exception"); onSIGEXIT.emit(); }); 30 | ::signal( SIGSEGV, []( int param ){ onSIGERROR.emit(SIGSEGV); conio::error("SIGSEGV: "); console::log("Segmentation Violation"); onSIGEXIT.emit(); }); 31 | ::signal( SIGILL, []( int param ){ onSIGERROR.emit(SIGILL ); conio::error("SIGILL: "); console::log("Illegal Instruction"); onSIGEXIT.emit(); }); 32 | ::signal( SIGTERM, []( int param ){ onSIGERROR.emit(SIGTERM); conio::error("SIGTERM: "); console::log("Process Terminated"); onSIGEXIT.emit(); }); 33 | ::signal( SIGINT, []( int param ){ onSIGERROR.emit(SIGINT ); conio::error("SIGINT: "); console::log("Signal Interrupt"); onSIGEXIT.emit(); }); 34 | #ifdef SIGPIPE 35 | ::signal( SIGPIPE, []( int param ){ onSIGERROR.emit(SIGPIPE); conio::error("SIGPIPE: "); console::log("Broked Pipeline"); onSIGEXIT.emit(); }); 36 | ::signal( SIGKILL, []( int param ){ onSIGERROR.emit(SIGKILL); conio::error("SIGKILL: "); console::log("Process Killed"); onSIGEXIT.emit(); }); 37 | #endif 38 | ::signal( SIGABRT, []( int param ){ onSIGERROR.emit(SIGABRT); conio::error("SIGABRT: "); console::log("Process Abort"); onSIGEXIT.emit(); }); 39 | // ::atexit( /*----*/ []( /*-----*/ ){ /*------------------------------------------------------------------------------------------*/ onSIGEXIT.emit(); }); 40 | #ifdef SIGPIPE 41 | ::signal( SIGPIPE, SIG_IGN ); 42 | #endif 43 | } 44 | 45 | inline void unignore( int signal ){ ::signal( signal, SIG_DFL ); } 46 | inline void ignore( int signal ){ ::signal( signal, SIG_IGN ); } 47 | inline void emit( int signal ){ ::raise ( signal ); } 48 | 49 | } 50 | 51 | }} 52 | 53 | /*────────────────────────────────────────────────────────────────────────────*/ 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/nodepp/posix/npoll.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_POSIX_NPOLL 13 | #define NODEPP_POSIX_NPOLL 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { enum POLL_STATE { 18 | READ = 1, WRITE = 2, DUPLEX = 3 19 | };} 20 | 21 | /*────────────────────────────────────────────────────────────────────────────*/ 22 | 23 | namespace nodepp { class poll_t : public generator_t { 24 | private: 25 | 26 | using NODE_CLB = function_t; 27 | struct waiter { bool blk; bool out; }; 28 | 29 | protected: 30 | 31 | struct NODE { 32 | queue_t queue; 33 | }; ptr_t obj; 34 | 35 | public: 36 | 37 | virtual ~poll_t() noexcept {} 38 | /*----*/ poll_t() noexcept : obj( new NODE() ) {} 39 | 40 | /*─······································································─*/ 41 | 42 | void clear() const noexcept { /*--*/ obj->queue.clear(); } 43 | 44 | ulong size() const noexcept { return obj->queue.size (); } 45 | 46 | bool empty() const noexcept { return obj->queue.empty(); } 47 | 48 | /*─······································································─*/ 49 | 50 | inline int next() noexcept { 51 | coBegin 52 | 53 | if( obj->queue.empty() ) /*-*/ { coEnd; } do { 54 | if( obj->queue.get()==nullptr ){ coEnd; } 55 | 56 | auto x = obj->queue.get(); 57 | auto y = x->data(); 58 | 59 | switch( y ){ 60 | case -1: obj->queue.erase(x); break; 61 | case 1: obj->queue.next(); break; 62 | default: /*--------------*/ break; 63 | } 64 | 65 | return y; } while(0); 66 | 67 | coFinish } 68 | 69 | /*─······································································─*/ 70 | 71 | template< class T, class U, class... W > 72 | void* add( T, uchar, U cb, const W&... args ) noexcept { 73 | 74 | ptr_t tsk = new waiter(); /*----------*/ 75 | auto clb=type::bind(cb); tsk->blk=0; tsk->out=1; 76 | 77 | obj->queue.push([=](){ 78 | if( tsk->out==0 ){ return -1; } 79 | if( tsk->blk==1 ){ return 1; } 80 | tsk->blk =1; int rs=(*clb)( args... ); 81 | if( clb.null() ){ return -1; } 82 | tsk->blk =0; return !tsk->out?-1:rs; 83 | }); 84 | 85 | return (void*) &tsk->out; 86 | } 87 | 88 | };} 89 | 90 | /*────────────────────────────────────────────────────────────────────────────*/ 91 | 92 | #endif 93 | 94 | /*────────────────────────────────────────────────────────────────────────────*/ -------------------------------------------------------------------------------- /test/map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace MAP { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | map initialization", [](){ 18 | try { 19 | map_t map ({ 20 | { "var1", 10 }, 21 | { "var2", 20 }, 22 | { "var3", 30 }, 23 | }); 24 | if ( map.size() != 3 ){ throw 0; } 25 | TEST_DONE(); 26 | } catch ( ... ) { TEST_FAIL(); } 27 | }); 28 | 29 | TEST_ADD( test, "TEST 2 | map searching", [](){ 30 | try { 31 | map_t map ({ 32 | { "var1", 10 }, 33 | { "var2", 20 }, 34 | { "var3", 30 }, 35 | }); 36 | if ( !map.has("var1") ){ throw 0; } 37 | TEST_DONE(); 38 | } catch ( ... ) { TEST_FAIL(); } 39 | }); 40 | 41 | TEST_ADD( test, "TEST 2 | map indexation", [](){ 42 | try { 43 | map_t map ({ 44 | { "var1", 10 }, 45 | { "var2", 20 }, 46 | { "var3", 30 }, 47 | }); 48 | map["var4"] = 40; 49 | if ( !map.has("var4") ){ throw 0; } 50 | TEST_DONE(); 51 | } catch ( ... ) { TEST_FAIL(); } 52 | }); 53 | 54 | TEST_ADD( test, "TEST 4 | map deindexation", [](){ 55 | try { 56 | map_t map ({ 57 | { "var1", 10 }, 58 | { "var2", 20 }, 59 | { "var3", 30 }, 60 | }); 61 | map.erase("var2"); 62 | if ( map.has("var2") ){ throw 0; } 63 | TEST_DONE(); 64 | } catch ( ... ) { TEST_FAIL(); } 65 | }); 66 | 67 | TEST_ADD( test, "TEST 4 | map clearing", [](){ 68 | try { 69 | map_t map ({ 70 | { "var1", 10 }, 71 | { "var2", 20 }, 72 | { "var3", 30 }, 73 | }); map.clear(); 74 | if ( !map.empty() ){ throw 0; } 75 | TEST_DONE(); 76 | } catch ( ... ) { TEST_FAIL(); } 77 | }); 78 | 79 | test.onClose.once([=](){ 80 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 81 | }); 82 | 83 | test.onDone([=](){ (*done)++; (*totl)++; }); 84 | test.onFail([=](){ (*err)++; (*totl)++; }); 85 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 86 | 87 | TEST_AWAIT( test ); 88 | 89 | } 90 | 91 | }} -------------------------------------------------------------------------------- /include/nodepp/observer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_OBSERVER 13 | #define NODEPP_OBSERVER 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | #include "wait.h" 18 | #include "type.h" 19 | #include "map.h" 20 | #include "any.h" 21 | 22 | /*────────────────────────────────────────────────────────────────────────────*/ 23 | 24 | namespace nodepp { class observer_t { 25 | private: 26 | 27 | map_t /*-*/ list ; 28 | wait_t event; 29 | 30 | using P=type::pair; 31 | using F=function_t; 32 | 33 | public: observer_t() noexcept {} 34 | 35 | /*─······································································─*/ 36 | 37 | template< ulong N > 38 | observer_t( const P (&args) [N] ) noexcept { ulong x=N; while( x-->0 ){ 39 | list[args[x].first] = args[x].second; 40 | }} 41 | 42 | virtual ~observer_t() noexcept {} 43 | 44 | /*─······································································─*/ 45 | 46 | template< class F > 47 | void set( string_t name, const F& value ) const { 48 | if( !list.has( name ) ){ throw except_t("field not found:",name); } 49 | auto n = list[ name ]; event.emit( name, n, value ); 50 | /*----*/ list[ name ]= value; 51 | } 52 | 53 | const any_t get( string_t name ) const { if( !list.has( name ) ){ 54 | throw except_t( "field not found:", name ); 55 | } return list[ name ]; } 56 | 57 | /*─······································································─*/ 58 | 59 | const any_t operator[]( string_t name ) const { return get( name ); } 60 | 61 | /*─······································································─*/ 62 | 63 | void off( void* addr ) const noexcept { event.off(addr); } 64 | 65 | void* once( string_t name, F func ) const noexcept { 66 | if( !list.has( name ) ){ return nullptr; } 67 | if( func.empty() ){ return nullptr; } 68 | return event.once( name, func ); 69 | } 70 | 71 | void* on( string_t name, F func ) const noexcept { 72 | if( !list.has( name ) ){ return nullptr; } 73 | if( func.empty() ){ return nullptr; } 74 | return event.on( name, func ); 75 | } 76 | 77 | /*─······································································─*/ 78 | 79 | void clear() const noexcept { list.clear(); event.clear(); } 80 | 81 | bool empty() const noexcept { return list.empty(); } 82 | 83 | ulong size() const noexcept { return list.size(); } 84 | 85 | };} 86 | 87 | /*────────────────────────────────────────────────────────────────────────────*/ 88 | 89 | #endif 90 | 91 | /*────────────────────────────────────────────────────────────────────────────*/ 92 | -------------------------------------------------------------------------------- /include/nodepp/any.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_ANY 13 | #define NODEPP_ANY 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { class any_t { 18 | public: 19 | 20 | any_t( const char* f ) noexcept { set( string::to_string(f) ); } 21 | 22 | any_t( null_t ) noexcept { /*---------*/ } 23 | 24 | template< class T > 25 | any_t( const T& f ) noexcept { set( f ); } 26 | 27 | virtual ~any_t() noexcept {} 28 | 29 | /*----*/ any_t() noexcept {} 30 | 31 | /*─······································································─*/ 32 | 33 | ulong type_size() const noexcept { return empty() ?0 : any_ptr->size(); } 34 | ulong count() const noexcept { return any_ptr.count(); } /*--------*/ 35 | bool empty() const noexcept { return any_ptr.null (); } /*--------*/ 36 | bool has_value() const noexcept { return !any_ptr.null (); } /*--------*/ 37 | void free() const noexcept { /*--*/ any_ptr.free (); } /*--------*/ 38 | 39 | /*─······································································─*/ 40 | 41 | template< class T > 42 | void set( const T& f ) noexcept { any_ptr = new any_impl(f); } 43 | 44 | template< class T > 45 | T as() const { return get(); } 46 | 47 | template< class T > 48 | T get() const { 49 | 50 | if( !has_value() ) /*----*/ { throw except_t("any_t is null"); } /*---------*/ 51 | if( type_size()!=sizeof(T) ){ throw except_t("any_t incompatible sizetype"); } 52 | 53 | const ulong size = sizeof(T) / sizeof(char); 54 | char any[ size ]; any_ptr->get((void*)&any); 55 | return *(T*)(any); /*---------------------*/ 56 | 57 | } 58 | 59 | /*─······································································─*/ 60 | 61 | template< class T > 62 | explicit operator T(void) const noexcept { return get(); } 63 | 64 | private: 65 | 66 | class any_base { 67 | public: 68 | virtual ~any_base() noexcept {} 69 | virtual void get( void* /*unused*/ ) const noexcept {} 70 | virtual void set( void* /*unused*/ ) /*-*/ noexcept {} 71 | virtual ulong size() /*------------*/ const noexcept =0; 72 | }; 73 | 74 | /*─······································································─*/ 75 | 76 | template< class T > 77 | class any_impl : public any_base { 78 | public: 79 | any_impl( const T& f ) noexcept : any( type::bind(f) ) {} 80 | virtual ulong size() /*------*/ const noexcept { return any.null(/**/) ?0 : sizeof(T) ; } 81 | virtual void get( void* argc ) const noexcept { memcpy( argc, (void*)&any, sizeof(T) ); } 82 | virtual void set( void* argc ) /*-*/ noexcept { memcpy( (void*)&any, argc, sizeof(T) ); } 83 | private: 84 | ptr_t any; 85 | }; 86 | 87 | /*─······································································─*/ 88 | 89 | ptr_t any_ptr; 90 | 91 | };} 92 | 93 | /*────────────────────────────────────────────────────────────────────────────*/ 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /test/event.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace EVENT { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | event initialization 1", [](){ 18 | try { ptr_t x = new int(0); 19 | event_t<> event; event.on([=](){ *x=1; }); 20 | event.emit(); 21 | if ( event.empty() ){ throw 0; } 22 | if ( *x==0 )/*----*/{ throw 0; } 23 | TEST_DONE(); 24 | } catch ( ... ) { TEST_FAIL(); } 25 | }); 26 | 27 | TEST_ADD( test, "TEST 2 | event initialization 2", [](){ 28 | try { ptr_t x = new int(0); 29 | event_t event; event.on([=]( int y ){ *x=y; }); 30 | event.emit(1); 31 | if ( event.empty() ){ throw 0; } 32 | if ( *x==0 )/*----*/{ throw 0; } 33 | TEST_DONE(); 34 | } catch ( ... ) { TEST_FAIL(); } 35 | }); 36 | 37 | TEST_ADD( test, "TEST 3 | once execution", [](){ 38 | try { ptr_t x = new int(0); 39 | event_t<> event; event.once([=](){ *x+=1; }); 40 | event.emit(); event.emit(); event.emit(); 41 | if ( *x!=1 )/**/{ throw 0; } 42 | TEST_DONE(); 43 | } catch ( ... ) { TEST_FAIL(); } 44 | }); 45 | 46 | TEST_ADD( test, "TEST 4 | on execution", [](){ 47 | try { ptr_t x = new int(0); 48 | event_t<> event; event.on([=](){ *x+=1; }); 49 | event.emit(); event.emit(); event.emit(); 50 | if ( event.empty() ){ throw 0; } 51 | if ( *x!=3 )/*----*/{ throw 0; } 52 | TEST_DONE(); 53 | } catch ( ... ) { TEST_FAIL(); } 54 | }); 55 | 56 | TEST_ADD( test, "TEST 5 | skipping", [](){ 57 | try { ptr_t x = new int(0); 58 | event_t<> event; event.on([=](){ *x+=1; }); 59 | event.stop(); event.emit(); 60 | event.resume(); event.emit(); event.emit(); 61 | if ( event.empty() ){ throw 0; } 62 | if ( *x!=2 )/*----*/{ throw 0; } 63 | TEST_DONE(); 64 | } catch ( ... ) { TEST_FAIL(); } 65 | }); 66 | 67 | TEST_ADD( test, "TEST 6 | stopping", [](){ 68 | try { ptr_t x = new int(0); 69 | event_t<> event; event.on([=](){ *x+=1; }); 70 | event.stop(); event.emit(); 71 | event.emit(); event.emit(); 72 | if ( event.empty() ){ throw 0; } 73 | if ( *x!=0 )/*----*/{ throw 0; } 74 | TEST_DONE(); 75 | } catch ( ... ) { TEST_FAIL(); } 76 | }); 77 | 78 | test.onClose.once([=](){ 79 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 80 | }); 81 | 82 | test.onDone([=](){ (*done)++; (*totl)++; }); 83 | test.onFail([=](){ (*err)++; (*totl)++; }); 84 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 85 | 86 | TEST_AWAIT( test ); 87 | 88 | } 89 | 90 | }} -------------------------------------------------------------------------------- /include/nodepp/event.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_EVENT 13 | #define NODEPP_EVENT 14 | 15 | /*────────────────────────────────────────────────────────────────────────────*/ 16 | 17 | namespace nodepp { template< class... A > class event_t { 18 | protected: 19 | 20 | struct DONE { bool /**/ *out; 21 | function_t clb; 22 | }; 23 | 24 | struct NODE { 25 | char skip = 1; 26 | queue_t que; 27 | }; ptr_t obj; 28 | 29 | public: 30 | 31 | /*----*/ event_t() noexcept : obj( new NODE() ) {} 32 | virtual ~event_t() noexcept { /*--------------*/ } 33 | 34 | /*─······································································─*/ 35 | 36 | void* operator()( function_t func ) const noexcept { return on(func); } 37 | 38 | /*─······································································─*/ 39 | 40 | void* once( function_t func ) const noexcept { 41 | if( func.empty() ){ return nullptr; } 42 | ptr_t out = new bool(1); DONE ctx; 43 | ctx.out=&out; ctx.clb=([=]( A... args ){ 44 | if(*out != 0 ){ func(args...); } /*------------------*/ 45 | if( out.null() ){ return false; } *out = 0; return *out; 46 | }); obj->que.push(ctx); return obj->que.last(); 47 | } 48 | 49 | void* on( function_t func ) const noexcept { 50 | if( func.empty() ){ return nullptr; } 51 | ptr_t out = new bool(1); DONE ctx; 52 | ctx.out=&out; ctx.clb=([=]( A... args ){ 53 | if(*out != 0 ){ func(args...); } /*--------*/ 54 | if( out.null() ){ return false; } return *out; 55 | }); obj->que.push(ctx); return obj->que.last(); 56 | } 57 | 58 | void off( void* address ) const noexcept { 59 | auto node = obj->que.get(address); 60 | if ( node == nullptr ){ return; } 61 | /**/ obj->que.erase( node ); 62 | } 63 | 64 | /*─······································································─*/ 65 | 66 | bool empty() const noexcept { return obj->que.empty(); } 67 | ulong size() const noexcept { return obj->que.size (); } 68 | void clear() const noexcept { /*--*/ obj->que.clear(); } 69 | 70 | /*─······································································─*/ 71 | 72 | void emit( const A&... args ) const noexcept { 73 | if( obj.null() || is_paused() ){ return; } auto x=obj->que.first(); 74 | while( x!=nullptr && !obj->que.empty() ) { auto y=x->next; auto z=x->data; 75 | if ( *z.out == 0 ) /*---------------*/ { obj->que.erase( x ); } 76 | elif ( !z.clb(args...) ) /*-----------*/ { obj->que.erase( x ); } 77 | x=y; }} 78 | 79 | /*─······································································─*/ 80 | 81 | bool is_paused() const noexcept { return obj->skip<=0; } 82 | 83 | void resume() const noexcept { obj->skip = 1; } 84 | 85 | void stop() const noexcept { obj->skip = 0; } 86 | 87 | void skip() const noexcept { obj->skip =-1; } 88 | 89 | };} 90 | 91 | /*────────────────────────────────────────────────────────────────────────────*/ 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /test/wait.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace nodepp; 6 | 7 | namespace TEST { namespace WAIT { 8 | 9 | void TEST_RUNNER(){ 10 | ptr_t totl = new uint(0); 11 | ptr_t done = new uint(0); 12 | ptr_t err = new uint(0); 13 | ptr_t skp = new uint(0); 14 | 15 | auto test = TEST_CREATE(); 16 | 17 | TEST_ADD( test, "TEST 1 | wait initialization 1", [](){ 18 | try { ptr_t x = new int(0); 19 | wait_t wait; wait.on("test",[=](){ *x=1; }); 20 | wait.emit("test"); 21 | if ( wait.empty() ){ throw 0; } 22 | if ( *x==0 )/*---*/{ throw 0; } 23 | TEST_DONE(); 24 | } catch ( ... ) { TEST_FAIL(); } 25 | }); 26 | 27 | TEST_ADD( test, "TEST 2 | wait initialization 2", [](){ 28 | try { ptr_t x = new int(0); 29 | wait_t wait; wait.on("test",[=]( int y ){ *x=y; }); 30 | wait.emit("test",1); 31 | if ( wait.empty() ){ throw 0; } 32 | if ( *x==0 )/*---*/{ throw 0; } 33 | TEST_DONE(); 34 | } catch ( ... ) { TEST_FAIL(); } 35 | }); 36 | 37 | TEST_ADD( test, "TEST 3 | once execution", [](){ 38 | try { ptr_t x = new int(0); 39 | wait_t wait; wait.once("test",[=](){ *x+=1; }); 40 | wait.emit("test"); wait.emit("test"); wait.emit("test"); 41 | if ( *x!=1 )/**/{ throw 0; } 42 | TEST_DONE(); 43 | } catch ( ... ) { TEST_FAIL(); } 44 | }); 45 | 46 | TEST_ADD( test, "TEST 4 | on execution", [](){ 47 | try { ptr_t x = new int(0); 48 | wait_t wait; wait.on("test",[=](){ *x+=1; }); 49 | wait.emit("test"); wait.emit("test"); wait.emit("test"); 50 | if ( wait.empty() ){ throw 0; } 51 | if ( *x!=3 )/*---*/{ throw 0; } 52 | TEST_DONE(); 53 | } catch ( ... ) { TEST_FAIL(); } 54 | }); 55 | 56 | TEST_ADD( test, "TEST 5 | skipping", [](){ 57 | try { ptr_t x = new int(0); 58 | wait_t wait; wait.on("test",[=](){ *x+=1; }); 59 | wait.stop(); wait.emit("test"); 60 | wait.resume(); wait.emit("test"); wait.emit("test"); 61 | if ( wait.empty() ){ throw 0; } 62 | if ( *x!=2 )/*---*/{ throw 0; } 63 | TEST_DONE(); 64 | } catch ( ... ) { TEST_FAIL(); } 65 | }); 66 | 67 | TEST_ADD( test, "TEST 6 | stopping", [](){ 68 | try { ptr_t x = new int(0); 69 | wait_t wait; wait.on("test",[=](){ *x+=1; }); 70 | wait.stop(); wait.emit("test"); 71 | wait.emit("test"); wait.emit("test"); 72 | if ( wait.empty() ){ throw 0; } 73 | if ( *x!=0 )/*---*/{ throw 0; } 74 | TEST_DONE(); 75 | } catch ( ... ) { TEST_FAIL(); } 76 | }); 77 | 78 | test.onClose.once([=](){ 79 | console::log("\nRESULT | total:", *totl, "| passed:", *done, "| error:", *err, "| skipped:", *skp ); 80 | }); 81 | 82 | test.onDone([=](){ (*done)++; (*totl)++; }); 83 | test.onFail([=](){ (*err)++; (*totl)++; }); 84 | test.onSkip([=](){ (*skp)++; (*totl)++; }); 85 | 86 | TEST_AWAIT( test ); 87 | 88 | } 89 | 90 | }} -------------------------------------------------------------------------------- /include/nodepp/ws.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Nodepp Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the MIT (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://github.com/NodeppOfficial/nodepp/blob/main/LICENSE 8 | */ 9 | 10 | /*────────────────────────────────────────────────────────────────────────────*/ 11 | 12 | #ifndef NODEPP_WS 13 | #define NODEPP_WS 14 | #define NODEPP_WS_SECRET "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 15 | 16 | /*────────────────────────────────────────────────────────────────────────────*/ 17 | 18 | #include "http.h" 19 | #include "crypto.h" 20 | #include "generator.h" 21 | 22 | /*────────────────────────────────────────────────────────────────────────────*/ 23 | 24 | namespace nodepp { class ws_t : public socket_t { 25 | protected: 26 | 27 | struct NODE { 28 | generator::ws::write write; 29 | generator::ws::read read ; 30 | }; ptr_t ws; 31 | 32 | public: 33 | 34 | virtual ~ws_t() noexcept {} 35 | 36 | template< class... T > 37 | ws_t( const T&... args ) noexcept : socket_t( args... ), ws( new NODE() ){} 38 | 39 | virtual int _write( char* bf, const ulong& sx ) const noexcept override { 40 | if( is_closed() ){ return -1; } if( sx==0 ){ return 0; } 41 | while( ws->write( this, bf, sx )==1 ){ return -2; } 42 | return ws->write.data==0 ? -1 : ws->write.data; 43 | } 44 | 45 | virtual int _read ( char* bf, const ulong& sx ) const noexcept override { 46 | if( is_closed() ){ return -1; } if( sx==0 ){ return 0; } 47 | while( ws->read( this, bf, sx )==1 ){ return -2; } 48 | return ws->read.data==0 ? -1 : ws->read.data; 49 | } 50 | 51 | };} 52 | 53 | /*────────────────────────────────────────────────────────────────────────────*/ 54 | 55 | namespace nodepp { namespace ws { 56 | 57 | inline tcp_t server( const tcp_t& skt ){ skt.onSocket([=]( socket_t cli ){ 58 | 59 | auto hrv = type::cast(cli); 60 | if( !generator::ws::server( hrv ) ) 61 | { skt.onConnect.skip(); return; } 62 | 63 | process::add([=](){ 64 | skt.onConnect.resume( ); 65 | skt.onConnect.emit(cli); 66 | return -1; 67 | }); 68 | 69 | }); skt.onConnect([=]( ws_t cli ){ 70 | cli.onDrain.once([=](){ cli.free(); }); 71 | cli.set_timeout(0); cli.resume(); stream::pipe(cli); 72 | }); return skt; } 73 | 74 | /*─······································································─*/ 75 | 76 | inline tcp_t server( agent_t* opt=nullptr ){ 77 | auto skt = http::server( nullptr, opt ); 78 | ws::server( skt ); return skt; 79 | } 80 | 81 | /*─······································································─*/ 82 | 83 | inline tcp_t client( const string_t& uri, agent_t* opt=nullptr ){ 84 | tcp_t skt ( nullptr, opt ); 85 | skt.onSocket.once([=]( socket_t cli ){ 86 | 87 | auto hrv = type::cast (cli); 88 | if( !generator::ws::client( hrv, uri ) ) 89 | { skt.onConnect.skip(); return; } 90 | 91 | process::add([=](){ 92 | skt.onConnect.resume( ); 93 | skt.onConnect.emit(cli); 94 | return -1; 95 | }); 96 | 97 | }); skt.onConnect.once([=]( ws_t cli ){ 98 | cli.onDrain.once([=](){ cli.free(); }); 99 | cli.set_timeout(0); cli.resume(); stream::pipe(cli); 100 | }); skt.connect( url::hostname(uri), url::port(uri) ); return skt; } 101 | 102 | }} 103 | 104 | #undef NODEPP_WS_SECRET 105 | #endif --------------------------------------------------------------------------------