Midnight Cow / ThingerIO

Dependencies:   DHT WIZnetInterface mbed-src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers thinger_resource.hpp Source File

thinger_resource.hpp

00001 // The MIT License (MIT)
00002 //
00003 // Copyright (c) 2015 THINGER LTD
00004 // Author: alvarolb@gmail.com (Alvaro Luis Bustamante)
00005 //
00006 // Permission is hereby granted, free of charge, to any person obtaining a copy
00007 // of this software and associated documentation files (the "Software"), to deal
00008 // in the Software without restriction, including without limitation the rights
00009 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010 // copies of the Software, and to permit persons to whom the Software is
00011 // furnished to do so, subject to the following conditions:
00012 //
00013 // The above copyright notice and this permission notice shall be included in
00014 // all copies or substantial portions of the Software.
00015 //
00016 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00019 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00020 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00021 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00022 // THE SOFTWARE.
00023 
00024 #ifndef THINGER_RESOURCE_HPP
00025 #define THINGER_RESOURCE_HPP
00026 
00027 #include "thinger_map.hpp"
00028 #include "pson.h"
00029 #include "thinger_message.hpp"
00030 
00031 namespace thinger{
00032 
00033 
00034 class thinger_resource {
00035 
00036 public:
00037     enum io_type {
00038         none                = 0,
00039         run                 = 1,
00040         pson_in             = 2,
00041         pson_out            = 3,
00042         pson_in_pson_out    = 4
00043     };
00044 
00045     enum access_type{
00046         PRIVATE     = 0,
00047         PROTECTED   = 1,
00048         PUBLIC      = 2,
00049         NONE        = 3
00050     };
00051 
00052 private:
00053 
00054     union callback{
00055         void (*run)();
00056         void (*pson_in)(protoson::pson& in);
00057         void (*pson_out)(protoson::pson& out);
00058         void (*pson_in_pson_out)(protoson::pson& in, protoson::pson& out);
00059     };
00060 
00061     io_type io_type_;
00062     access_type access_type_;
00063     callback callback_;
00064     thinger_map<thinger_resource> sub_resources_;
00065 
00066 public:
00067     thinger_resource() : io_type_(none), access_type_(PRIVATE)
00068     {
00069     }
00070 
00071     thinger_resource * find(const char* res)
00072     {
00073         return sub_resources_.find(res);
00074     }
00075 
00076     thinger_resource & operator[](const char* res){
00077         return sub_resources_[res];
00078     }
00079 
00080     thinger_resource & operator()(access_type type){
00081         access_type_ = type;
00082         return *this;
00083     }
00084 
00085     io_type get_io_type(){
00086         return io_type_;
00087     }
00088 
00089     access_type get_access_type(){
00090         return access_type_;
00091     }
00092 
00093     void fill_api(protoson::pson_object& content){
00094         if(io_type_!=none){
00095             content["al"] = access_type_;
00096             content["fn"] = io_type_;
00097         }
00098         thinger_map<thinger_resource>::entry* current = sub_resources_.begin();
00099         if(current!=NULL){
00100             protoson::pson_object& actions = content["/"];
00101             do{
00102                 current->value_.fill_api(actions[current->key_]);
00103                 current = current->next_;
00104             }while(current!=NULL);
00105         }
00106     }
00107 
00108     void fill_api_io(protoson::pson_object& content){
00109         if(io_type_ == pson_in){
00110             callback_.pson_in(content["in"]);
00111         }else if(io_type_ == pson_out){
00112             callback_.pson_out(content["out"]);
00113         }else if(io_type_ == pson_in_pson_out){
00114             callback_.pson_in_pson_out(content["in"], content["out"]);
00115         }
00116         // initialize empty objects if the function is input or output but there is no any value defined
00117         if((io_type_ == pson_in || io_type_ == pson_in_pson_out) && content["in"].is_empty()){
00118             protoson::pson_object& empty_object = content["in"];
00119         }
00120         if((io_type_ == pson_out || io_type_ == pson_in_pson_out) && content["out"].is_empty()){
00121             protoson::pson_object& empty_object = content["out"];
00122         }
00123     }
00124 
00125 public:
00126 
00127     /**
00128      * Establish a function without input or output parameters
00129      */
00130     void operator=(void (*run_function)()){
00131         io_type_ = run;
00132         callback_.run = run_function;
00133     }
00134 
00135     /**
00136      * Establish a function with input parameters
00137      */
00138     void operator<<(void (*in_function)(protoson::pson& in)){
00139         io_type_ = pson_in;
00140         callback_.pson_in = in_function;
00141     }
00142 
00143     /**
00144      * Establish a function that only generates an output
00145      */
00146     void operator>>(void (*out_function)(protoson::pson& out)){
00147         io_type_ = pson_out;
00148         callback_.pson_out = out_function;
00149     }
00150 
00151     /**
00152      * Establish a function that can receive input parameters and generate an output
00153      */
00154     void operator=(void (*pson_in_pson_out_function)(protoson::pson& in, protoson::pson& out)){
00155         io_type_ = pson_in_pson_out;
00156         callback_.pson_in_pson_out = pson_in_pson_out_function;
00157     }
00158 
00159     void handle_request(thinger_message& request, thinger_message& response){
00160         switch (io_type_){
00161             case run:
00162                 callback_.run();
00163                 break;
00164             case pson_in:
00165                 callback_.pson_in(request);
00166                 break;
00167             case pson_out:
00168                 callback_.pson_out(response);
00169                 break;
00170             case pson_in_pson_out:
00171                 callback_.pson_in_pson_out(request, response);
00172                 break;
00173             case none:
00174                 break;
00175         }
00176     }
00177 };
00178 
00179 }
00180 
00181 #endif