#include "PikaObj.h" #include "dataArgs.h" #include "dataMemory.h" #include "dataString.h" #include "dataStrs.h" #include "PikaInvoke.h" #include #include "PikaBlock.h" #include "PikaIf.h" #include "PikaWhile.h" PikaObj *obj_getContext(PikaObj *self) { return obj_getPtr(self, "_ctx"); } void *getNewObjFunByClass(PikaObj *obj, char *classPath) { PikaObj *classLoader = args_getPtr(obj->attributeList, "_clsld"); if (NULL == classLoader) { return NULL; } void *(*newObjFun)(Args * initArgs) = args_getPtr(classLoader->attributeList, classPath); return newObjFun; } int32_t deinitEachSubObj(Arg *argEach, Args *handleArgs) { if (NULL != handleArgs) { /* error: tOhis handle not need handle args */ return 1; } char *type = arg_getType(argEach); if (strIsStartWith(type, "_class")) { PikaObj *subObj = arg_getPtr(argEach); if (NULL != subObj) { obj_deinit(subObj); } } return 0; } void deinitAllSubObj(PikaObj *self) { Args *args = self->attributeList; args_foreach(args, deinitEachSubObj, NULL); } int32_t obj_deinit(PikaObj *self) { deinitAllSubObj(self); args_deinit(self->attributeList); //DynMemPut(self->mem); pikaFree(self, sizeof(PikaObj)); self = NULL; return 0; } int32_t obj_enable(PikaObj *self) { obj_setInt(self, "isEnable", 1); return 0; } int32_t obj_disable(PikaObj *self) { obj_setInt(self, "isEnable", 0); return 0; } int32_t obj_setInt(PikaObj *self, char *argPath, int64_t val) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { /* [error] object no found */ return 1; } Args *buffs = New_strBuff(); char *name = strsGetLastToken(buffs, argPath, '.'); args_setInt(obj->attributeList, name, val); args_deinit(buffs); return 0; } int32_t obj_setPtr(PikaObj *self, char *argPath, void *pointer) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return 1; } Args *buffs = New_strBuff(); char *name = strsGetLastToken(buffs, argPath, '.'); args_setPtr(obj->attributeList, name, pointer); args_deinit(buffs); return 0; } int32_t obj_setFloat(PikaObj *self, char *argPath, float value) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return 1; } Args *buffs = New_strBuff(); char *name = strsGetLastToken(buffs, argPath, '.'); args_setFloat(obj->attributeList, name, value); args_deinit(buffs); return 0; } int32_t obj_setStr(PikaObj *self, char *argPath, char *str) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return 1; } Args *buffs = New_strBuff(); char *name = strsGetLastToken(buffs, argPath, '.'); args_setStr(obj->attributeList, name, str); args_deinit(buffs); return 0; } int64_t obj_getInt(PikaObj *self, char *argPath) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return -999999999; } Args *buffs = New_strBuff(); char *argName = strsGetLastToken(buffs, argPath, '.'); int res = args_getInt(obj->attributeList, argName); args_deinit(buffs); return res; } Arg *obj_getArg(PikaObj *self, char *argPath) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return NULL; } Args *buffs = New_strBuff(); char *argName = strsGetLastToken(buffs, argPath, '.'); Arg *res = args_getArg(obj->attributeList, argName); args_deinit(buffs); return res; } int32_t obj_setArg(PikaObj *self, char *argPath, Arg *arg) { /* setArg would copy arg */ PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { /* object no found */ return 1; } args_copyArg(obj->attributeList, arg); return 0; } void *obj_getPtr(PikaObj *self, char *argPath) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return NULL; } Args *buffs = New_strBuff(); char *argName = strsGetLastToken(buffs, argPath, '.'); void *res = args_getPtr(obj->attributeList, argName); args_deinit(buffs); return res; } float obj_getFloat(PikaObj *self, char *argPath) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return -999.999; } Args *buffs = New_strBuff(); char *argName = strsGetLastToken(buffs, argPath, '.'); float res = args_getFloat(obj->attributeList, argName); args_deinit(buffs); return res; } char *obj_getStr(PikaObj *self, char *argPath) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { return NULL; } Args *buffs = New_strBuff(); char *argName = strsGetLastToken(buffs, argPath, '.'); char *res = args_getStr(obj->attributeList, argName); args_deinit(buffs); return res; } int32_t obj_load(PikaObj *self, Args *args, char *name) { args_copyArgByName(args, name, self->attributeList); return 0; } int32_t obj_setObjWithoutClass(PikaObj *self, char *objName, void *newFun) { /* class means subprocess init */ Args *buffs = New_strBuff(); char *mataObjName = strsAppend(buffs, "[mate]", objName); obj_setPtr(self, mataObjName, newFun); /* add void object Ptr, no inited */ args_setObjectWithClass(self->attributeList, objName, "none", NULL); args_deinit(buffs); return 0; } int32_t obj_addOther(PikaObj *self, char *subObjectName, void *new_ObjectFun) { Args *initArgs = New_args(NULL); args_setPtr(initArgs, "_ctx", self); void *(*new_Object)(Args * initArgs) = (void *(*)(Args *))new_ObjectFun; void *subObject = new_Object(initArgs); obj_setPtr(self, subObjectName, subObject); args_deinit(initArgs); return 0; } int32_t obj_freeObj(PikaObj *self, char *objPath) { PikaObj *obj = obj_getPtr(self, objPath); obj_deinit(obj); return 0; } int32_t obj_bind(PikaObj *self, char *type, char *name, void *pointer) { args_bind(self->attributeList, type, name, pointer); return 0; } char *obj_print(PikaObj *self, char *name) { if (NULL == self) { return NULL; } return args_print(self->attributeList, name); } int32_t obj_bindInt(PikaObj *self, char *name, int32_t *valPtr) { args_bindInt(self->attributeList, name, valPtr); return 0; } int32_t obj_bindFloat(PikaObj *self, char *name, float *valPtr) { args_bindFloat(self->attributeList, name, valPtr); return 0; } int32_t obj_bindString(PikaObj *self, char *name, char **valPtr) { args_bindStr(self->attributeList, name, valPtr); return 0; } int32_t obj_set(PikaObj *self, char *argPath, char *valStr) { PikaObj *obj = obj_getObj(self, argPath, 1); if (NULL == obj) { /* cant get object */ return 3; } Args *buffs = New_strBuff(); char *argName = strsGetLastToken(buffs, argPath, '.'); int32_t res = args_set(obj->attributeList, argName, valStr); args_deinit(buffs); if (res == 1) { /* do not get arg */ return 1; } if (res == 2) { /* type not match */ return 2; } /* succeed */ return 0; } PikaObj *obj_getClassObjByNewFun(PikaObj *context, char *name, NewFun newClassFun) { Args *initArgs = New_args(NULL); args_setPtr(initArgs, "_ctx", context); args_setStr(initArgs, "_n", name); PikaObj *thisClass = newClassFun(initArgs); obj_setPtr(thisClass, "_clsptr", newClassFun); args_deinit(initArgs); return thisClass; } char *obj_getClassPath(PikaObj *objHost, Args *buffs, char *objName) { Arg *objArg = obj_getArg(objHost, objName); char *objType = arg_getType(objArg); char *classPath = strsRemovePrefix(buffs, objType, "_class-"); return classPath; } void *getNewClassObjFunByName(PikaObj *obj, char *name) { Args *buffs = New_strBuff(); char *classPath = strsAppend(buffs, "[mate]", name); /* init the subprocess */ void *(*newClassObjFun)(Args * initArgs) = args_getPtr(obj->attributeList, classPath); args_deinit(buffs); return newClassObjFun; } int32_t removeEachMethodInfo(Arg *argNow, Args *argList) { if (strIsStartWith(arg_getName(argNow), "[md]")) { args_removeArg(argList, arg_getName(argNow)); return 0; } if (strIsStartWith(arg_getName(argNow), "[mp]")) { args_removeArg(argList, arg_getName(argNow)); return 0; } return 0; } PikaObj *removeMethodInfo(PikaObj *thisClass) { args_foreach(thisClass->attributeList, removeEachMethodInfo, thisClass->attributeList); return thisClass; } static void removeClassLoader(PikaObj *obj) { PikaObj *classLoader = args_getPtr(obj->attributeList, "_clsld"); if (NULL != classLoader) { obj_deinit(classLoader); args_removeArg(obj->attributeList, "_clsld"); } } PikaObj *newRootObj(char *name, NewFun newObjFun) { PikaObj *thisClass = obj_getClassObjByNewFun(NULL, name, newObjFun); PikaObj *newObj = removeMethodInfo(thisClass); return newObj; } PikaObj *initObj(PikaObj *obj, char *name) { PikaObj *res = NULL; NewFun newObjFun = getNewClassObjFunByName(obj, name); Args *buffs = New_args(NULL); if (NULL == newObjFun) { /* no such object */ res = NULL; goto exit; } PikaObj *thisClass = obj_getClassObjByNewFun(obj, name, newObjFun); PikaObj *newObj = removeMethodInfo(thisClass); /* delete [mate] */ obj_removeArg(obj, strsAppend(buffs, "[mate]", name)); /* delete "_clsld" object */ removeClassLoader(newObj); char *type = args_getType(obj->attributeList, name); args_setPtrWithType(obj->attributeList, name, type, newObj); res = obj_getPtr(obj, name); goto exit; exit: args_deinit(buffs); return res; } PikaObj *obj_getObjDirect(PikaObj *self, char *name) { if (NULL == self) { return NULL; } /* check subprocess */ if (NULL == args_getPtr(self->attributeList, name)) { /* no inited subprocess, check subprocess init fun*/ return initObj(self, name); } /* finded subscribe, check type*/ char *type = args_getType(self->attributeList, name); if (!strIsStartWith(type, "_class")) { /* type error, could not found subprocess */ return NULL; } return obj_getPtr(self, name); } PikaObj *obj_getObj(PikaObj *self, char *objPath, int32_t keepDeepth) { Args *buffs = New_strBuff(); char *objPathBuff = strsCopy(buffs, objPath); int32_t tokenNum = strGetTokenNum(objPath, '.'); PikaObj *obj = self; for (int32_t i = 0; i < tokenNum - keepDeepth; i++) { char *token = strsPopToken(buffs, objPathBuff, '.'); obj = obj_getObjDirect(obj, token); if (obj == NULL) { goto exit; } } goto exit; exit: args_deinit(buffs); return obj; } char *obj_getName(PikaObj *self) { return obj_getStr(self, "_n"); } void loadMethodInfo(PikaObj *methodHost, char *methodName, char *methodDeclearation, void *methodPtr) { Args *buffs = New_strBuff(); char *methodPtrPath = strsAppend(buffs, "[mp]", methodName); char *methodDeclearationPath = strsAppend(buffs, "[md]", methodName); obj_setPtr(methodHost, methodPtrPath, methodPtr); obj_setStr(methodHost, methodDeclearationPath, methodDeclearation); args_deinit(buffs); } int32_t class_defineMethod(PikaObj *self, char *declearation, void (*methodPtr)(PikaObj *self, Args *args)) { int32_t size = strGetSize(declearation); int32_t res = 0; Args *buffs = New_strBuff(); char *cleanDeclearation = strDeleteChar(args_getBuff(buffs, size), declearation, ' '); char *methodPath = strGetFirstToken(args_getBuff(buffs, size), cleanDeclearation, '('); PikaObj *methodHost = obj_getObj(self, methodPath, 1); if (NULL == methodHost) { /* no found method object */ res = 1; goto exit; } char *methodName = strsGetLastToken(buffs, methodPath, '.'); loadMethodInfo(methodHost, methodName, cleanDeclearation, methodPtr); res = 0; goto exit; exit: args_deinit(buffs); return res; } static void transferReturnVal(PikaObj *self, char *returnType, char *returnName, Args *args) { if (strEqu("->int", returnType)) { int returnVal = args_getInt(args, "return"); obj_setInt(self, returnName, returnVal); return; } if (strEqu("->float", returnType)) { float returnVal = args_getFloat(args, "return"); obj_setFloat(self, returnName, returnVal); return; } if (strEqu("->str", returnType)) { char *returnVal = args_getStr(args, "return"); obj_setStr(self, returnName, returnVal); return; } } char *getRightCmd(Args *buffs, char *cmd) { char *right = NULL; char *cmdBuff = strsCopy(buffs, cmd); if (strIsContain(cmd, '(')) { cmdBuff = strsGetFirstToken(buffs, cmdBuff, '('); } if (strIsContain(cmdBuff, '=')) { cmdBuff = strsCopy(buffs, cmd); strsPopToken(buffs, cmdBuff, '='); right = cmdBuff; } else { right = cmd; } return right; } uint8_t obj_getAnyArg(PikaObj *self, char *targetArgName, char *sourceArgPath, Args *targetArgs) { if (0 == args_setLiteral(targetArgs, targetArgName, sourceArgPath)) { return 0; } if (0 == obj_getRefArg(self, targetArgName, sourceArgPath, targetArgs)) { return 0; } /* solve arg faild */ return 3; } uint8_t obj_getRefArg(PikaObj *self, char *targetArgName, char *sourceArgPath, Args *targetArgs) { /* get reference arg */ Arg *arg = obj_getArg(self, sourceArgPath); if (arg == NULL) { /* can not get arg */ return 3; } Arg *argCopied = arg_copy(arg); argCopied = arg_setName(argCopied, targetArgName); args_setArg(targetArgs, argCopied); return 0; } Args *getRightRes(PikaObj *self, char *cmd) { Args *buffs = New_strBuff(); Args *res = NULL; if (strIsContain(cmd, '(') && strIsContain(cmd, ')')) { res = obj_invoke(self, cmd); goto exit; } res = New_args(NULL); args_setSysOut(res, ""); int err = obj_getAnyArg(self, "return", cmd, res); if (err != 0) { args_setSysOut(res, "[error] get value faild."); args_setErrorCode(res, 1); goto exit; } char *returnType = args_getType(res, "return"); returnType = strsAppend(buffs, "->", returnType); args_setStr(res, "returnType", returnType); goto exit; exit: args_deinit(buffs); return res; } Args *obj_runScript(PikaObj *self, char *cmd) { Args *buffs = New_strBuff(); Args *res = NULL; cmd = strsGetCleanCmd(buffs, cmd); /* get right cmd */ char *right = getRightCmd(buffs, cmd); /* get res from right cmd */ res = getRightRes(self, right); if (NULL != res) { if (0 != args_getErrorCode(res)) { goto exit; } } /* check res */ if (NULL == res) { res = New_args(NULL); args_setErrorCode(res, 1); args_setSysOut(res, "[error] solve script format faild!"); goto exit; } /* transfer return */ if (strIsContain(cmd, '=')) { char *returnName = strsGetFirstToken(buffs, cmd, '='); returnName = strsDeleteChar(buffs, returnName, ' '); char *returnType = args_getStr(res, "returnType"); transferReturnVal(self, returnType, returnName, res); } exit: args_deinit(buffs); return res; } Args *obj_runDirect(PikaObj *self, char *cmd) { Args *buffs = New_strBuff(); Args *res = NULL; cmd = strsDeleteChar(buffs, cmd, '\n'); /* in block */ if (NULL != obj_getArg(self, "_isInBlock")) { PikaObj *block = obj_getObj(self, "_block", 0); if (strIsStartWith(cmd, " ")) { if (strEqu(block_getMode(block), "if")) { if_pushLine(block, cmd); goto exit; } if (strEqu(block_getMode(block), "while")) { while_pushLine(block, cmd); goto exit; } goto exit; } /* the block is end */ else { obj_removeArg(self, "_isInBlock"); if (strEqu(block_getMode(block), "if")) { if_run(block); } if (strEqu(block_getMode(block), "while")) { while_run(block); } obj_removeArg(self, "_block"); /* not finished */ } } /* if block */ if (strIsStartWith(cmd, "if ")) { obj_setInt(self, "_isInBlock", 1); obj_setObjWithoutClass(self, "_block", block_init); PikaObj *block = obj_getObj(self, "_block", 0); if_setAssert(block, cmd); /* this line processed ok */ goto exit; } /* while block */ if (strIsStartWith(cmd, "while ")) { obj_setInt(self, "_isInBlock", 1); obj_setObjWithoutClass(self, "_block", block_init); PikaObj *block = obj_getObj(self, "_block", 0); while_setAssert(block, cmd); /* this line processed ok */ goto exit; } /* run script */ if (strIsContain(cmd, '(') && strIsContain(cmd, ')')) { res = obj_runScript(self, cmd); goto exit; } /* run script */ if (strIsContain(cmd, '=')) { res = obj_runScript(self, cmd); goto exit; } exit: /* check res */ if (NULL == res) { res = New_args(NULL); args_setErrorCode(res, 0); args_setSysOut(res, ""); goto exit; } args_deinit(buffs); return res; } int32_t obj_removeArg(PikaObj *self, char *argPath) { PikaObj *objHost = obj_getObj(self, argPath, 1); PikaObj *obj = obj_getObj(self, argPath, 0); Args *buffs = New_strBuff(); if (NULL != obj) { obj_deinit(obj); } int32_t err = 0; if (NULL == objHost) { /* [error] object no found */ err = 1; goto exit; } char *argName = strsGetLastToken(buffs, argPath, '.'); int32_t res = args_removeArg(objHost->attributeList, argName); if (1 == res) { /*[error] not found arg*/ err = 2; goto exit; } goto exit; exit: args_deinit(buffs); return err; } int32_t obj_isArgExist(PikaObj *self, char *argPath) { PikaObj *obj = obj_getObj(self, argPath, 1); Args *buffs = New_strBuff(); int32_t res = 0; if (NULL == obj) { /* [error] object no found */ res = 1; goto exit; } char *argName = strsGetLastToken(buffs, argPath, '.'); Arg *arg = args_getArg(obj->attributeList, argName); if (NULL == arg) { /* no found arg */ res = 0; goto exit; } /* found arg */ res = 1; goto exit; exit: args_deinit(buffs); return res; } void obj_runNoRes(PikaObj *slef, char *cmd) { /* unsafe, nothing would happend when error occord */ args_deinit(obj_runDirect(slef, cmd)); } void obj_run(PikaObj *self, char *cmd) { /* safe, stop when error occord and error info would be print32_t */ Args *res = obj_runDirect(self, cmd); char *sysOut = args_getSysOut(res); uint8_t errcode = args_getErrorCode(res); obj_setSysOut(self, sysOut); obj_setErrorCode(self, errcode); if (!strEqu("", sysOut)) { printf("%s\r\n", sysOut); } if (0 != errcode) { printf("[info] input commond: %s\r\n", cmd); while (1) ; } if (NULL != res) { args_deinit(res); } } void obj_setErrorCode(PikaObj *self, int32_t errCode) { obj_setInt(self, "__errCode", errCode); } int32_t obj_getErrorCode(PikaObj *self) { if (!obj_isArgExist(self, "__errCode")) { return 0; } return obj_getInt(self, "__errCode"); } void args_setErrorCode(Args *args, int32_t errCode) { args_setInt(args, "__errCode", errCode); } int32_t args_getErrorCode(Args *args) { if (!args_isArgExist(args, "__errCode")) { return 0; } return args_getInt(args, "__errCode"); } void obj_setSysOut(PikaObj *self, char *str) { obj_setStr(self, "__sysOut", str); } char *obj_getSysOut(PikaObj *self) { return obj_getStr(self, "__sysOut"); } char *args_getSysOut(Args *args) { return args_getStr(args, "__sysOut"); } void args_setSysOut(Args *args, char *str) { args_setStr(args, "__sysOut", str); } void obj_sysPrintf(PikaObj *self, char *fmt, ...) { va_list args; va_start(args, fmt); char sysOut[128] = {0}; vsprintf(sysOut, fmt, args); obj_setSysOut(self, sysOut); va_end(args); }