# uci import file # native import string import json # really a a nested map designe to work like a javascript object with . notation class Object var _obj var _autosave # will save object(map) whenever changes are made, default: false var _autoload # if true will attempt to load from file on init, default: true var _status var file # attached file instance var _deep # depth to follow nested maps, default = -1 which mean walk until no more # forbidden key names # any key starting with _ # init # member # setmember # assign # retrieve # load # save # get # set # file # filename # exporti # importi # for passing only opts must set obj to {} or nil, e.g. (nil,{'autosave':true}) def init(obj,filename,opts) if (type(obj) == 'string') if debug[3] print('no object passed a filename was passed') end opts = filename filename = obj obj = nil end if isinstance(filename, map) opts = filename filename = nil end if ! opts opts = {} end self.assign(self._isMap(obj,true)) # will set to empty map if obj is nil if filename if debug[3] print('filename passsed, adding file instance', filename) end self.file = file(filename,opts.find('ext')) # create file instance end self._autosave = opts.find('autosave') == nil ? false : opts.find('autosave') self._autoload = opts.find('autoload') == nil ? true : opts.find('autoload') if self.file if self._isMap(obj) if self._autosave if debug[3] print('autosaving passed object map to', self.file.name()) end self.save() end else if self._autoload if debug[3] print('autoloading', self.file.name()) end return self.load() end end end end # def load (filename) if self.file if debug[3] print ('loading before', self._obj) end var obj = self.file.load(filename) if isinstance(obj,map) self._obj = obj return obj # walk object looking for additional maps? else if debug[3] print ('Warning: Unable to load file or file does not contain a map') end end if debug[3] print ('loading after',self._obj) end end return nil end def save (filename) if self.file if debug[3] print ('saving', self.file.addext(filename)) print ('object to be saved', self._obj) # print ('contents of current file', self.load(filename)) end self.file.save(self._obj,filename) # if debug[3] print ('after saving',self.load(filename)) end end end def _isMap (m,init) if isinstance(m, map) return m else if init return {} else return nil end end end def merge(m,overwrite) for k: m.keys() if overwrite self._obj.setitem(k,m[k]) else self._obj.insert(k,m[k]) end end return self._obj end def assign(obj) if ! obj obj={} end if isinstance(obj, map) self._obj=obj else end return self._obj end def retrieve() return self._obj end def exporti(save) var obj = self._obj if save && self.file self.save() obj = nil end return { 'filename': self.filename(), 'obj':obj, 'opts':{'autosave':self._autosave, 'autoload':self._autoload} } end def importi(s) print ('setting to import',s) return Object(s.item('obj'),s.item('filename'),s.item('opts')) end def filename() if self.file return self.file.name() else return nil end end def del(keys) self.set(keys,'__remove__') end # # sets a nested property def set(keys,value) def _set(keys,value,obj) if !obj obj = self._obj end var key = keys.pop() if !obj.find(key) obj[key] = {} end if keys.size() return _set(keys,value,obj[key]) else if value == '__remove__' obj.remove(key) else obj[key]=value end return true end end if type(keys) == 'string' keys = string.split(keys,".") end if !isinstance(keys,list) print('ERROR: list of keys not passed', keys) return nil end keys.reverse() if debug[3] print('setting',keys,'to',value) end if _set(keys,value) if self.file && self._autosave self.save() end end end def dump(subkey) if subkey == nil return json.dump(self.get()) end return json.dump(self.get(subkey)) end # gets a nested property def get(keys) if keys == nil return self._obj end def _get(keys,obj) if !obj obj = self._obj end var key = keys.pop() var _obj = obj.find(key) if debug[1] print('current key:', key, 'remaining keys:', keys ) print('current nested object: ',_obj) end if isinstance(_obj,map) if keys.size() return _get(keys,_obj) else return _obj end else return _obj end end if type(keys) == 'string' keys = string.split(keys,".") end if !isinstance(keys,list) print('ERROR: list of keys not passed', keys) return nil end keys.reverse() if debug[3] print('getting',keys) end return _get(keys) end # - virtual member getter, if a key does not exists return `nil`-# def member(key) return self._obj.find(key) end #- virtual member setter -# def setmember(key, value) if debug[3] print ('setting key=>', key,':', value) end self._obj[key] = value if self._autosave self.save() end return self.member(key) end end # Object Class var object = module('object') object = Object return object