Giter Site home page Giter Site logo

kojiba / raylanguage Goto Github PK

View Code? Open in Web Editor NEW
54.0 7.0 7.0 6.75 MB

Additions to C functional. (Containers, strings operations, memory operations, sockets, threads, etc...)

License: BSD 2-Clause "Simplified" License

C 90.72% C++ 2.03% Objective-C 5.32% CMake 1.94%
lib navive winapi-posix c std bytes threads array dictionary buffer

raylanguage's Introduction

RayFoundation

Firstly:

Runtime components, creates open and secure integrated library
for application development(like NextStep.CoreFoundation for POSIX + winAPI).

Secondly:

ONLY 120 KB 4all, CARL!
Use RayConfig.h to reduce size to 100KB, by removing warnings and error strings.
Can be compiled to use only CoreObjects like strings and containers using RAY_EMBEDDED 82KB!

Thirdly:

Ray additions to C language defines some C-based syntax,
that makes object-oriented life easier for C developers.
All based on defines and can use diff code style (RSyntax.h).

Containers:

  1. Array, List - NSArray, std::vector, list analog
  2. Dictionary - NSDictionary, std::map analog
  3. Buffer - store full copy of objects
  4. Data - base sized data class for strings, and bytes

Strings and raw bytes:

  1. Wide range of string processing operations (RString)
  2. Replacings
  3. Find of substring or symbol
  4. Delete characters/substrings
  5. Delete of duplications characters/substring
  6. Compares
  7. Read from file/ apend to file
  8. Tokenization into container Array
  9. Base64 encoding/decoding
  10. etc...

System dependent Utils (WINAPI + POSIX):

  1. RThread and RThreadPool
  2. RSocket (WINAPI + Berkley)
  3. RTCPHandler - multi-threaded tcp server engine

Memory operations:

  1. Easy sandboxing and testing with logging
  2. Memory management with RAutoPool (Checking leaks, manage allocations)
  3. Work with byte buffers and memory chunks

Some test projects based on RayFoundation:

  1. Simple VM with Brainfuck compiler and execution visualization in Curses
  2. Simple TCP multi-threaded text-chat with 'nc' util client

Change code style guide:

Howto 4 change code style

Work with RArray:

#include <RayFoundation.h>

typedef struct ComplexStruct {
    size_t id;
    RString *fullName;
} ComplexStruct;

void printComplexStruct(ComplexStruct *some) {
    printf("%p | id: %02lu | fullname : \'%s\' \n", some, some->id, some->fullName->baseString);
}

void complexDeleter(ComplexStruct *some) {
    deleter(some->fullName, RString);
    free(some);
}

int main(int argc, const char *argv[]) {
    size_t iterator;

    RArray *array = makeRArray(); // create array
    // sets delegates for automatic print and cleanup
    array->printerDelegate = (PrinterDelegate) printComplexStruct;
    array->destructorDelegate = (DestructorDelegate) complexDeleter;

    forAll(iterator, 100) {
        // create struct and add to array
        ComplexStruct *some = malloc(sizeof(ComplexStruct));
        some->id = iterator + 1;
        some->fullName = stringWithFormat("Object # %lu", iterator + 1); // more string processing API in RString.h
        $(array, m(addObject, RArray)), some);
    }
    // print
    printerOfRArray(array);

    // delete, automatically calls destructor delegate and free array prt
    deleter(array, RArray);

    // some syntaxic sugar see initFromArray, initFromArrayWithSizes, arrayFromArray

    // create array of strings
    RString *uniqTok = RS("Unique token");
    array = RA(RS("Token 1"), RS("Token 2"), uniqTok, nil); // must be NULL terminated

    array->printerDelegate = (PrinterDelegate) p(RString);
    array->destructorDelegate = free;

    printerOfRArray(array);

    RCompareDelegate delegate;
    delegate.etaloneObject = uniqTok;
    delegate.virtualCompareMethod = (RCompareFlags (*)(pointer, pointer)) compareWithRString;

    RFindResult result = findObjectWithDelegateRArray(array, &delegate); // search

    if(result.object != nil) { // object != nil -> found object, place also logged
        printf("Found some object at place %lu!\n", result.index);
    } else {
        printf("Object not found!\n");
    }

    RArray *subarray = getSubarrayRArray(array, makeRRange(1, 2)); // delegates will be copied
    printerOfRArray(subarray);
    subarray->destructorDelegate = nil; // not want to delete strings
    deleter(subarray, RArray);

    deleter(array, RArray); // cleanup strings

    return 0;
}

RDictionary use:

#include <RayFoundation.h>
#include "Tests.h"

int main(int argc, const char *argv[]) {
    enablePool(RPool);
    ComplexTest();

    RDictionary *dict =  dictionaryFromPairs("key", "value",
                                             "key2", "value2",
                                             "key3", "value3",
                                             "key4", "value4",
                                             "key5", "value5",
                                             nil);

    char * string = $(dict, m(getObjectForKey, RDictionary)), "key4");

    printf("Found object for \'key4\' - \'%s\' \n\n", string);

    deleter(dict, RDictionary);

    endRay(); // standart cleanup
}

BrainFuck samples:

#include "RayFoundation/RayFoundation.h"
#include "RVirtualMachine/RVirtualFunction/RVirtualFunction.h"
#include "RVirtualMachine/RVirtualMachine/RVirtualMachine.h"
#include "RVirtualMachine/RVirtualCompiler.h"

int main(int argc, const char *argv[]) {
    // ezy brainfuck hello world
    RVirtualFunction *function = $(RVC, m(createFunctionFromBrainFuckSourceCode, RVirtualCompiler)),
            RS(" My brainfuck hello world : +++++++++++++++++++++++++++++++++++++++++++++\n"
                    " +++++++++++++++++++++++++++.+++++++++++++++++\n"
                    " ++++++++++++.+++++++..+++.-------------------\n"
                    " ---------------------------------------------\n"
                    " ---------------.+++++++++++++++++++++++++++++\n"
                    " ++++++++++++++++++++++++++.++++++++++++++++++\n"
                    " ++++++.+++.------.--------.------------------\n"
                    " ---------------------------------------------\n"
                    " ----.-----------------------."));

    // execute of byte-code on RVM singleton
    executeRay(function);
    $(function, d(RVirtualFunction)) );

    // brainfuck compiler multiple-cycles test
    function = $(RVC, m(createFunctionFromBrainFuckSourceCode, RVirtualCompiler)),
            RS(" Cycles : +++ [ > +++ [.-] <-]")); // prints '03 02 01' 3-times
    executeRay(function);
    $(function, d(RVirtualFunction)) );

    // brainfuck hard(with [, ]) hello world on RVM
    function = $(RVC, m(createFunctionFromBrainFuckSourceCode, RVirtualCompiler)),
            RS(" Hard Hello world : ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++\n"
                                  " .>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.\n"
                                  " ------.--------.>+.>."));

    // rasm byte-code print in words
    $(function, p(RVirtualFunction)) );

    executeRay(function);
    $(function, d(RVirtualFunction)) );
    
    // final function delete
    deallocator(function);

    // RVM singleton cleanup
    deleteRVM();
    endRay(); // standart cleanup
}

RAutoPool:

int main(int argc, const char *argv[]) {
    initPointers();
    enablePool(RPool); // enable pool sinleton
    ComplexTest();     // do something 

    $(RPool, p(RAutoPool)));   // check leaks
    deleter(RPool, RAutoPool); // total cleanup 
    return 0;
    // or use macro endRay -> standart cleanup
}

Work with RClassTable:

#include "RayFoundation/RClassTable/RClassTable.h"

void RClassTableTest(void){

    // register class name once, and get identifier in result
    // it's can be used like management tool for creating unique 
    // identifiers for string objects (in our case class names)
    
    registerClassOnce("Luke");
    // print our class table
    printRCTS;

    registerClassOnce("Dart");
    printRCTS;

    registerClassOnce("Leia");
    printRCTS;
    
    // try once more, but here is only one record
    registerClassOnce("Leia");
    registerClassOnce("Dart");
    registerClassOnce("Luke");
    registerClassOnce("Han Solo");
    printRCTS;
    // get Identifier of Han Solo
    char *checkName = "Han Solo";
    RPrintf("Identifier of %s is - %qu \n", checkName, registerClassOnce(checkName));
    
    // flush your class table
    flushRCTS;
    printRCTS;
    
    // delete your class table
    releaseRCTS;
    
    // use not singleton
    RClassTable *table = makeRCTable();

    $(table, m(registerClassWithName, RClassTable)), "Some string");
    $(table, m(registerClassWithName, RClassTable)), "Some string2");
    $(table, m(registerClassWithName, RClassTable)), "Some string3");
    // once more time, to check
    $(table, m(registerClassWithName, RClassTable)), "Some string3");

    $(table, p(RClassTable)) );

    $(table, d(RClassTable)) );
    deallocator(table);
}

You can simply use it in Yours C++ projects:

#include <iostream>

#include "RayFoundation.h"

using namespace std;

class MyClass{
protected:
    double x;
    double y;
public:
    MyClass(){

    }
    ~MyClass(){

    }
    void Print(){
        cout << "MyClass obj - " << this << endl;
    }
};

void deleter(pointer src) {
    delete (MyClass*)src;
}

void Printer(pointer src){
    ((MyClass*)src)->Print();
}

int main(int argc, const char *argv[]) {

    RArray *helloArray = makeRArray();

    helloArray->destructorDelegate = deleter;
    helloArray->printerDelegate = Printer;

    for(unsigned i = 0; i < 100000; ++i) {
        MyClass *a = new MyClass;
        addObjectRArray(helloArray, a);
    }

    $(helloArray, p(RArray)));
    deleteRA(helloArray);
    return 0;
}

Some multi-thread tcp-echo server sample on RTCPHandler:

#include <RayFoundation/RayFoundation.h>

#include "Tests.h"

#define BUFFER_SIZE 1500

pointer exec(RTCPDataStruct *data) {
    char    buffer[BUFFER_SIZE];
    const char    *address = addressToString(&data->socket->address);
    ushort            port = ntohs(data->socket->address.sin_port);
    unsigned currentThread =  (unsigned int) currentThreadIdentifier();
    byte     resultFlag;
    size_t   receivedSize;

    RPrintf("[I] %s:%u connected [tuid : %u]\n", address, port, currentThread);

    $(data->socket, m(sendString, RSocket)), RS("Hello from RServer.\n"));

    resultFlag = $(data->socket, m(receive, RSocket)), buffer, 1000, &receivedSize);
    while(resultFlag != networkConnectionClosedConst) {
        buffer[receivedSize] = 0;
        RPrintf("%s:%u[%u] > %s", address, port, currentThread, buffer);
        $(data->socket, m(send, RSocket)), buffer, receivedSize);
        resultFlag =  $(data->socket, m(receive, RSocket)), buffer, BUFFER_SIZE, &receivedSize);
    }

    RPrintf("[I] %s:%u disconnected [tuid : %u]\n", address, port, currentThread);

    deleter(data->socket, RSocket);
    data->socket = nil; // for auto-cleaning
    return nil;
}

RTCPHandler  *server   = nil;
RTCPDelegate *delegate = nil;

void startServer(void) {
    server = c(RTCPHandler)(nil);
    if(server != nil) {
        delegate = allocator(delegate);
        if(delegate != nil) {
            delegate->delegateFunction = (RThreadFunction) exec;
            delegate->context          = server;
            $(server,  m(set_delegate, RTCPHandler)), delegate);
            RPrintf("RTCPHandler starting %p\n", server);
            $(server,  m(startOnPort, RTCPHandler)), 4000);
        }
    }
}

int main(int argc, const char *argv[]) {
    rbool closeAll = no;
    byte connectionState;
    char buffer[BUFFER_SIZE];
    const char *address;
    ushort port;
    RSocket *configurator;
    size_t  receivedSize;

    enablePool(RPool);
    ComplexTest(); // lib test

    startServer();

    configurator = openListenerOnPort(4001, 10);
    if(configurator == nil) goto exit;

    while(!closeAll) {
        RSocket *current = $(configurator, m(accept, RSocket)));

        address = addressToString(&current->address);
        port    = ntohs(current->address.sin_port);

        RPrintf("[I] Configurator %s:%u connected\n", address, port);
        connectionState = networkOperationSuccessConst;

        while(connectionState != networkConnectionClosedConst) {
            connectionState = $(current, m(receive, RSocket)), buffer, BUFFER_SIZE, &receivedSize);
            if(connectionState == networkOperationSuccessConst) {
                if(receivedSize > 8) {
                    buffer[receivedSize] = 0;
                    ifMemEqual(buffer, "secretkey", 9) {

                        ifMemEqual(buffer + 10, "shutdown", 8) {
                            $(current, m(sendString, RSocket)), RS("Server will terminate\n"));
                            RPrintf("[I] Will terminate with command from %s:%u\n\n", address, port);

                            closeAll = yes;
                        }

                        ifMemEqual(buffer + 10, "system", 6) {
                            RPrintf(">> Execute %s", buffer + 17);
                            system(buffer + 17);
                        }

                    } else {
                        RPrintf("[E] Bad user key on %s:%u\n", address, port);
                    }
                }
                connectionState = networkConnectionClosedConst;
            } else if (connectionState == networkOperationErrorConst) {
                RError2("[E] Receive on configurator connection, from %s:%u", current, address, port);
            }
        }

        deleter(current, RSocket);
    }

    deleter(configurator, RSocket);

    deallocator(delegate);
    p(RTCPHandler)(server);
    $(server, m(terminate, RTCPHandler)));
    deleter(server,        RTCPHandler);

    exit:
    endSockets();
    endRay();
}

raylanguage's People

Contributors

kojiba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

raylanguage's Issues

Add tests

Would be great to see some kind of [unit]-tests for the library. I think this will help in finding bugs and documenting the API.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.