12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748 |
- /* Brain4it.js */
- if (typeof Brain4it === 'undefined') {
- var Brain4it = {}
- }
- Brain4it.idSequence = 0
- /* Reference class */
- Brain4it.Reference = function(name) {
- this.name = name
- }
- /* Structure class */
- Brain4it.Structure = function(size) {
- this.id = String(Brain4it.idSequence++)
- this.namesList = []
- this.nameToIndexMap = {}
- this.shared = false
- if (size !== undefined) {
- for (var i = 0; i < size; i++) {
- this.namesList.push(null)
- }
- }
- }
- Brain4it.Structure.prototype = {
- size: function() {
- return this.namesList.length
- },
- isShared: function() {
- return this.shared
- },
- setShared: function(shared) {
- this.shared = shared
- },
- add: function() {
- this.namesList.push(null)
- },
- insert: function(index) {
- this.shiftIndices(index, 1)
- this.namesList.splice(index, 0, null)
- },
- delete: function(index) {
- this.shiftIndices(index, -1)
- this.namesList.splice(index, 1)
- },
- putName: function(index, name) {
- if (index === this.namesList.length) {
- this.nameToIndexMap[name] = index
- this.namesList.push(name)
- } else if (index < this.namesList.length) {
- var oldName = this.namesList[index]
- if (oldName !== null) {
- delete this.nameToIndexMap[oldName]
- }
- if (name !== null) {
- var oldIndex = this.nameToIndexMap[name]
- this.nameToIndexMap[name] = index
- if (oldIndex !== null) {
- this.namesList[oldIndex] = null
- }
- }
- this.namesList[index] = name
- } else throw 'invalid index'
- },
- getName: function(index) {
- return this.namesList[index]
- },
- deleteName: function(index) {
- this.putName(index, null)
- },
- getIndex: function(name) {
- var index = this.nameToIndexMap[name]
- return index === undefined ? -1 : index
- },
- clone: function() {
- var structure = new Brain4it.Structure()
- for (var key in this.nameToIndexMap) {
- structure.nameToIndexMap[key] = this.nameToIndexMap[key]
- }
- for (var index = 0; index < this.namesList.length; index++) {
- structure.namesList.push(this.namesList[index])
- }
- return structure
- },
- shiftIndices: function(index, offset) {
- if (offset < 0) {
- var name = this.namesList[index]
- if (name !== null) {
- delete this.nameToIndexMap[name]
- }
- index++
- }
- while (index < this.namesList.length) {
- var name = this.namesList[index]
- if (name !== null) {
- this.nameToIndexMap[name] = index + offset
- }
- index++
- }
- }
- }
- /* List class */
- Brain4it.List = function() {
- this.id = String(Brain4it.idSequence++)
- this.elements = []
- this.structure = null
- }
- Brain4it.List.prototype = {
- getStructure: function() {
- return this.structure
- },
- setStructure: function(structure) {
- structure.setShared(true)
- this.structure = structure
- if (this.elements.length > structure.size()) {
- this.elements.splice(structure.size(), this.elements.length - structure.size())
- } else if (this.elements.length < structure.size()) {
- for (var i = this.elements.length; i < structure.size(); i++) {
- this.elements.push(null)
- }
- }
- },
- add: function(element) {
- if (this.structure !== null) {
- this.modifyStructure()
- this.structure.add()
- }
- this.elements.push(element)
- },
- insert: function(index, element) {
- if (this.structure !== null) {
- this.modifyStructure()
- this.structure.insert(index)
- }
- this.elements.splice(index, 0, element)
- },
- size: function() {
- return this.elements.length
- },
- putByName: function(name, element) {
- var old
- var index
- if (this.structure === null) {
- this.structure = new Brain4it.Structure(this.elements.length)
- index = -1
- } else {
- index = this.structure.getIndex(name)
- }
- if (index === -1) {
- this.modifyStructure()
- this.structure.putName(this.elements.length, name)
- this.elements.push(element)
- old = null
- } else {
- old = this.elements[index]
- this.elements[index] = element
- }
- return old
- },
- getByName: function(name) {
- if (this.structure !== null) {
- var index = this.structure.getIndex(name)
- if (index !== -1) return this.elements[index]
- }
- return null
- },
- removeByName: function(name) {
- if (this.structure === null) return null
- var index = this.structure.getIndex(name)
- if (index === -1) return null
- return this.removeByIndex(index)
- },
- putByIndex: function(index, element) {
- var old = this.elements[index]
- this.elements[index] = element
- return old
- },
- getByIndex: function(index) {
- return this.elements[index]
- },
- removeByIndex: function(index) {
- if (this.structure !== null) {
- this.modifyStructure()
- this.structure.delete(index)
- }
- var old = this.elements[index]
- this.elements.splice(index, 1)
- return old
- },
- putName: function(index, name) {
- if (this.structure === null) {
- if (name === null) return
- this.structure = new Brain4it.Structure()
- } else {
- this.modifyStructure()
- }
- this.structure.putName(index, name)
- },
- getName: function(index) {
- if (this.structure === null) return null
- return this.structure.getName(index)
- },
- has: function(name) {
- if (this.structure === null) return false
- return this.structure.getIndex(name) !== -1
- },
- getIndexOfName: function(name) {
- if (this.structure === null) return -1
- return this.structure.getIndex(name)
- },
- modifyStructure: function() {
- if (this.structure.isShared()) {
- this.structure = this.structure.clone()
- }
- }
- }
- /* IO classes */
- Brain4it.OPEN_LIST_TOKEN = '('
- Brain4it.CLOSE_LIST_TOKEN = ')'
- Brain4it.NAME_OPERATOR_TOKEN = '=>'
- Brain4it.PATH_REFERENCE_SEPARATOR = '/'
- Brain4it.DECLARATION_TAG_PREFIX = '<#'
- Brain4it.DECLARATION_TAG_SUFFIX = '>'
- Brain4it.DECLARATION_TAG_SEPARATOR = ':'
- Brain4it.LINK_TAG_PREFIX = '<@'
- Brain4it.LINK_TAG_SUFFIX = '>'
- /* ServerConstants */
- Brain4it.MIMETYPE = 'text/plain'
- Brain4it.CHARSET = 'UTF-8'
- Brain4it.ACCESS_KEY_HEADER = 'access-key'
- Brain4it.MONITOR_HEADER = 'monitor'
- Brain4it.SESSION_ID_HEADER = 'session-id'
- Brain4it.SERVER_TIME_HEADER = 'server-time'
- Brain4it.MODULE_ACCESS_KEY_VAR = 'access-key'
- Brain4it.MODULE_METADATA_VAR = 'module-metadata'
- Brain4it.DASHBOARDS_FUNCTION_NAME = '@dashboards'
- Brain4it.unescapeString = function(text) {
- var escape = false
- var buffer = ''
- for (var i = 0; i < text.length; i++) {
- var ch = text.charAt(i)
- if (escape) {
- switch (ch) {
- case 'n':
- buffer += '\n'
- break
- case 'r':
- buffer += '\r'
- break
- case 't':
- buffer += '\t'
- break
- case '\\':
- buffer += '\\'
- break
- case 'b':
- buffer += '\b'
- break
- case 'f':
- buffer += '\f'
- break
- case "'":
- buffer += "'"
- break
- case '"':
- buffer += '"'
- break
- case 'u':
- var unicodeBuffer = text.substring(i + 1, i + 5)
- buffer += String.fromCharCode(parseInt(unicodeBuffer, 16))
- break
- default:
- throw new 'Invalid character: \\'() + ch
- }
- escape = false
- } else if (ch === '"') {
- } else if (ch === '\\') {
- escape = true
- } else {
- buffer += ch
- }
- }
- return buffer
- }
- Brain4it.escapeString = function(text) {
- if (text === null) return 'null'
- var buffer = ''
- for (var i = 0; i < text.length; i++) {
- var ch = text.charAt(i)
- if (ch === '\n') buffer += '\\n'
- else if (ch === '\r') buffer += '\\r'
- else if (ch === '\t') buffer += '\\t'
- else if (ch === '\\') buffer += '\\\\'
- else if (ch === '"') buffer += '\\"'
- else buffer += ch
- }
- return buffer
- }
- Brain4it.isNumber = function(value) {
- if (typeof value === 'number') {
- return true
- } else if (typeof value === 'string' && value.length > 0) {
- return String(Number(value)) !== 'NaN'
- }
- }
- Brain4it.mayBeNumber = function(value) {
- if (typeof value === 'number') {
- return true
- } else if (typeof value === 'string' && value.length > 0) {
- var firstChar = value.charAt(0)
- if (firstChar >= '0' && firstChar <= '9') return true
- if (value.length === 1) return false
- if (firstChar === '.') {
- var secondChar = value.charAt(1)
- return secondChar >= '0' && secondChar <= '9'
- } else if (firstChar === '+' || firstChar === '-') {
- var secondChar = value.charAt(1)
- if (secondChar >= '0' && secondChar <= '9') return true
- if (value.length === 2) return false
- if (secondChar === '.') {
- var thirdChar = value.charAt(2)
- return thirdChar >= '0' && thirdChar <= '9'
- }
- }
- }
- return false
- }
- Brain4it.DECLARATION_TAG_REGEX = new RegExp(Brain4it.DECLARATION_TAG_PREFIX + '..*' + Brain4it.DECLARATION_TAG_SUFFIX)
- Brain4it.LINK_TAG_REGEX = new RegExp(Brain4it.LINK_TAG_PREFIX + '..*' + Brain4it.LINK_TAG_SUFFIX)
- Brain4it.parseTag = function(text) {
- if (Brain4it.LINK_TAG_REGEX.test(text)) {
- return new Brain4it.LinkTag(text.substring(Brain4it.LINK_TAG_PREFIX.length, text.length - Brain4it.LINK_TAG_SUFFIX.length))
- } else if (Brain4it.DECLARATION_TAG_REGEX.test(text)) {
- var index = text.indexOf(Brain4it.DECLARATION_TAG_SEPARATOR, Brain4it.DECLARATION_TAG_PREFIX.length)
- if (index === -1) {
- return new Brain4it.DeclarationTag(text.substring(Brain4it.DECLARATION_TAG_PREFIX.length, text.length - Brain4it.DECLARATION_TAG_SUFFIX.length))
- } else if (index === Brain4it.DECLARATION_TAG_PREFIX.length) {
- return new Brain4it.DeclarationTag(null, text.substring(index + 1, text.length - Brain4it.DECLARATION_TAG_SUFFIX.length))
- } else {
- return new Brain4it.DeclarationTag(text.substring(Brain4it.DECLARATION_TAG_PREFIX.length, index), text.substring(index + 1, text.length - Brain4it.DECLARATION_TAG_SUFFIX.length))
- }
- }
- return null
- }
- /* DeclarationTag class */
- Brain4it.DeclarationTag = function(dataListId, structureListId) {
- this.dataListId = dataListId ? String(dataListId) : null
- this.structureListId = structureListId ? String(structureListId) : null
- }
- Brain4it.DeclarationTag.prototype = {
- toString: function() {
- var buffer = ''
- buffer += Brain4it.DECLARATION_TAG_PREFIX
- if (this.dataListId !== null) {
- buffer += this.dataListId
- }
- if (this.structureListId !== null && this.structureListId !== this.dataListId) {
- buffer += Brain4it.DECLARATION_TAG_SEPARATOR
- buffer += this.structureListId
- }
- buffer += Brain4it.DECLARATION_TAG_SUFFIX
- return buffer
- }
- }
- /* LinkTag class */
- Brain4it.LinkTag = function(dataListId) {
- this.dataListId = dataListId ? String(dataListId) : null
- }
- Brain4it.LinkTag.prototype = {
- toString: function() {
- return Brain4it.LINK_TAG_PREFIX + this.dataListId + Brain4it.LINK_TAG_SUFFIX
- }
- }
- /* Token class */
- Brain4it.Token = function() {
- this.type = null
- this.text = null
- this.startPosition = 0
- this.endPosition = 0
- this.object = null
- }
- Brain4it.Token.EOF = 'EOF'
- Brain4it.Token.NULL = 'NULL'
- Brain4it.Token.NUMBER = 'NUMBER'
- Brain4it.Token.STRING = 'STRING'
- Brain4it.Token.BOOLEAN = 'BOOLEAN'
- Brain4it.Token.REFERENCE = 'REFERENCE'
- Brain4it.Token.OPEN_LIST = 'OPEN_LIST'
- Brain4it.Token.CLOSE_LIST = 'CLOSE_LIST'
- Brain4it.Token.NAME_OPERATOR = 'NAME_OPERATOR'
- Brain4it.Token.TAG = 'TAG'
- Brain4it.Token.INVALID = 'INVALID'
- Brain4it.Token.prototype = {
- length: function() {
- return this.endPosition - this.startPosition
- }
- }
- /* Tokenizer class */
- Brain4it.Tokenizer = function(stream) {
- this.stream = stream
- this.charPosition = -1
- this.tokens = null // token stack
- }
- Brain4it.Tokenizer.prototype = {
- readToken: function(token) {
- if (this.tokens === null || this.tokens.length === 0) {
- token = this.readNextToken(token)
- } else {
- token = this.tokens.pop()
- }
- return token
- },
- unreadToken: function(token) {
- if (this.tokens === null) {
- this.tokens = []
- }
- this.tokens.push(token)
- },
- readNextToken: function(token) {
- if (token) {
- token.type = null
- token.text = null
- token.object = null
- token.startPosition = this.charPosition
- } else {
- token = new Brain4it.Token()
- }
- var state = 0
- var buffer = ''
- var pathBuffer = ''
- var end = false
- do {
- var ch = this.readChar()
- switch (state) {
- case 0: // Expecting new token
- if (ch === null) {
- token.startPosition = this.charPosition
- token.endPosition = this.charPosition
- token.type = Brain4it.Token.EOF
- token.text = ''
- this.unreadChar()
- end = true
- } else if (ch === Brain4it.OPEN_LIST_TOKEN) {
- token.startPosition = this.charPosition
- token.endPosition = this.charPosition + 1
- token.type = Brain4it.Token.OPEN_LIST
- token.text = Brain4it.OPEN_LIST_TOKEN
- end = true
- } else if (ch === Brain4it.CLOSE_LIST_TOKEN) {
- token.startPosition = this.charPosition
- token.endPosition = this.charPosition + 1
- token.type = Brain4it.Token.CLOSE_LIST
- token.text = Brain4it.CLOSE_LIST_TOKEN
- end = true
- } else if (this.isSeparator(ch)) {
- // skip
- } else if (ch === '"') {
- // start STRING
- buffer += ch
- token.startPosition = this.charPosition
- state = 1
- } else if (ch === Brain4it.PATH_REFERENCE_SEPARATOR) {
- pathBuffer += ch
- buffer = ''
- token.type = Brain4it.Token.REFERENCE
- token.startPosition = this.charPosition
- token.object = new Brain4it.List()
- state = 3
- } // start NUMBER, BOOLEAN, NULL or REFERENCE
- else {
- buffer += ch
- token.startPosition = this.charPosition
- state = 2
- }
- break
- case 1: // Processing String
- if (ch === null) {
- // unterminated string
- token.endPosition = this.charPosition
- token.type = Brain4it.Token.INVALID
- try {
- token.object = Brain4it.unescapeString(buffer)
- } catch (ex) {}
- token.text = buffer
- end = true
- } else if (ch === '\n' || ch === '\r' || ch === '\t') {
- token.endPosition = this.charPosition + 1
- token.type = Brain4it.Token.INVALID
- try {
- token.object = Brain4it.unescapeString(buffer)
- } catch (ex) {}
- token.text = buffer
- this.unreadChar()
- end = true
- } else if (ch === '"' && buffer.charAt(buffer.length - 1) !== '\\') {
- buffer += ch
- token.endPosition = this.charPosition + 1
- token.type = Brain4it.Token.STRING
- try {
- token.object = Brain4it.unescapeString(buffer)
- } catch (ex) {
- token.type = Brain4it.Token.INVALID
- }
- token.text = buffer
- end = true
- } else {
- buffer += ch
- }
- break
- case 2: // Processing token
- if (this.isSeparator(ch) || ch === Brain4it.OPEN_LIST_TOKEN || ch === Brain4it.CLOSE_LIST_TOKEN || ch === null) {
- if (token.type === Brain4it.Token.INVALID) {
- // return INVALID token
- } else if (buffer === 'true') {
- token.type = Brain4it.Token.BOOLEAN
- token.object = true
- } else if (buffer === 'false') {
- token.type = Brain4it.Token.BOOLEAN
- token.object = false
- } else if (buffer === 'null') {
- token.type = Brain4it.Token.NULL
- } else if (buffer === 'NaN') {
- token.type = Brain4it.Token.NUMBER
- token.object = NaN
- } else if (buffer === 'Infinity') {
- token.type = Brain4it.Token.NUMBER
- token.object = Infinity
- } else if (buffer === '-Infinity') {
- token.type = Brain4it.Token.NUMBER
- token.object = -Infinity
- } else if (Brain4it.mayBeNumber(buffer)) {
- try {
- token.object = Number(buffer)
- token.type = Brain4it.Token.NUMBER
- } catch (ex) {
- token.type = Brain4it.Token.INVALID
- }
- } else {
- var tag = Brain4it.parseTag(buffer)
- if (tag !== null) {
- token.object = tag
- token.type = Brain4it.Token.TAG
- } else {
- token.type = Brain4it.Token.REFERENCE
- }
- }
- token.text = buffer
- token.endPosition = this.charPosition
- this.unreadChar()
- end = true
- } else if (ch === '"') {
- buffer += ch
- token.type = Brain4it.Token.INVALID
- } else if (ch === Brain4it.PATH_REFERENCE_SEPARATOR) {
- token.type = Brain4it.Token.REFERENCE
- token.object = new Brain4it.List()
- this.unreadChar()
- state = 3
- } else {
- // add char to token
- buffer += ch
- if (buffer === Brain4it.NAME_OPERATOR_TOKEN) {
- token.object = null
- token.type = Brain4it.Token.NAME_OPERATOR
- token.endPosition = this.charPosition + 1
- token.text = Brain4it.NAME_OPERATOR_TOKEN
- end = true
- }
- }
- break
- case 3: // path reference name or index
- if (this.isSeparator(ch) || ch === Brain4it.OPEN_LIST_TOKEN || ch === Brain4it.CLOSE_LIST_TOKEN || ch === Brain4it.PATH_REFERENCE_SEPARATOR || ch === null) {
- pathBuffer += buffer
- if (buffer.length > 0) {
- if (buffer[0] >= '0' && buffer[0] <= '9') {
- try {
- token.object.add(parseInt(buffer))
- } catch (ex) {
- token.object.add(buffer)
- token.type = Brain4it.Token.INVALID
- }
- } else {
- if (buffer[0] === '"' && buffer[buffer.length - 1] === '"') {
- try {
- token.object.add(Brain4it.unescapeString(buffer))
- } catch (ex) {
- token.object.add(buffer)
- token.type = Brain4it.Token.INVALID
- }
- } else {
- token.object.add(buffer)
- if (buffer.indexOf('"') !== -1) {
- token.type = Brain4it.Token.INVALID
- }
- }
- }
- }
- if (ch === Brain4it.PATH_REFERENCE_SEPARATOR) {
- pathBuffer += ch
- buffer = ''
- } else {
- token.endPosition = this.charPosition
- token.text = pathBuffer
- if (token.object instanceof Brain4it.List) {
- if (token.object.size() === 0) {
- token.object = null
- }
- }
- this.unreadChar(ch)
- end = true
- }
- } else if (ch === '"') {
- buffer += ch
- state = 4
- } else {
- buffer += ch
- }
- break
- case 4: // path reference name string
- if (ch === null) {
- // unterminated string
- pathBuffer += buffer
- token.endPosition = this.charPosition
- token.type = Brain4it.Token.INVALID
- token.text = pathBuffer
- end = true
- } else if (ch === '\n' || ch === '\r' || ch === '\t') {
- pathBuffer += buffer
- token.endPosition = this.charPosition + 1
- token.type = Brain4it.Token.INVALID
- token.text = pathBuffer
- this.unreadChar(ch)
- end = true
- } else if (ch === '"' && buffer[buffer.length - 1] !== '\\') {
- buffer += ch
- state = 3
- } else {
- buffer += ch
- }
- default:
- }
- } while (!end)
- return token
- },
- readChar: function() {
- this.charPosition++
- if (this.charPosition >= this.stream.length) return null
- var ch = this.stream.charAt(this.charPosition)
- return ch
- },
- unreadChar: function() {
- if (this.charPosition >= 0) {
- this.charPosition--
- }
- },
- isSeparator: function(ch) {
- return ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r'
- }
- }
- /* Parser class */
- Brain4it.Parser = function() {
- this.tokenizer = null
- this.listsById = null
- this.structuredLists = null
- this.stack = null
- this.name = null
- }
- Brain4it.Parser.prototype = {
- parse: function(text) {
- this.tokenizer = new Brain4it.Tokenizer(text)
- this.listsById = {}
- this.structuredLists = {}
- this.stack = []
- this.name = null
- var result = null
- var token = new Brain4it.Token()
- this.tokenizer.readToken(token)
- var end = false
- do {
- if (token.type === Brain4it.Token.INVALID) {
- throw 'Invalid token: ' + token.text + ' at ' + token.startPosition
- } else if (token.type === Brain4it.Token.OPEN_LIST) {
- var list = new Brain4it.List()
- if (this.stack.length === 0) {
- result = list
- } else {
- this.addToCurrentList(list)
- }
- this.stack.push(list)
- } else if (token.type === Brain4it.Token.CLOSE_LIST) {
- if (this.stack.length > 0) {
- this.stack.pop()
- if (this.stack.length === 0) {
- end = true
- }
- } else throw 'Unmatched parentheses at ' + token.startPosition
- } else if (token.type === Brain4it.Token.NAME_OPERATOR) {
- if (this.stack.length === 0) throw 'Missing name at ' + token.startPosition
- var currentList = this.stack[this.stack.length - 1]
- if (currentList.size() === 0) throw 'Missing name at ' + token.startPosition
- var nameObject = currentList.removeByIndex(currentList.size() - 1)
- if (nameObject instanceof Brain4it.Reference) {
- this.name = nameObject.name
- } else {
- this.name = String(nameObject)
- }
- } else if (token.type === Brain4it.Token.TAG) {
- if (this.stack.length === 0) {
- throw 'Invalid tag at ' + token.startPosition
- } else {
- var tag = token.object
- var currentList = this.stack[this.stack.length - 1]
- if (tag instanceof Brain4it.DeclarationTag) {
- var dataListId = tag.dataListId
- if (dataListId !== null) {
- this.listsById[dataListId] = currentList
- }
- var structureListId = tag.structureListId
- if (structureListId !== null) {
- var list = this.listsById[structureListId]
- if (list === null) {
- throw new 'Invalid declaration tag at '() + token.startPosition
- }
- this.structuredLists[currentList.id] = [currentList, list.getStructure()]
- }
- } // LinkTag
- else {
- var dataListId = tag.dataListId
- var list = this.listsById[dataListId]
- if (list === null) throw 'Invalid link tag at ' + token.startPosition
- this.addToCurrentList(list)
- }
- }
- } else if (token.type === Brain4it.Token.REFERENCE) {
- var reference = new Brain4it.Reference(token.text)
- if (this.stack.length === 0) {
- result = reference
- end = true
- } else {
- this.addToCurrentList(reference)
- }
- } // Literals
- else {
- var object = token.object
- if (this.stack.length === 0) {
- result = object
- end = true
- } // add to current list
- else {
- this.addToCurrentList(object)
- }
- }
- this.tokenizer.readToken(token)
- } while (token.type !== Brain4it.Token.EOF && !end)
- if (!(end && token.type === Brain4it.Token.EOF)) throw 'Unmatched parenthesis at ' + token.startPosition
- for (var listId in this.structuredLists) {
- var pair = this.structuredLists[listId]
- var list = pair[0]
- var structure = pair[1]
- list.setStructure(structure)
- }
- return result
- },
- addToCurrentList: function(object) {
- var currentList = this.stack[this.stack.length - 1]
- if (this.name === null || this.structuredLists[currentList.id]) {
- currentList.add(object)
- } else {
- currentList.putByName(this.name, object)
- }
- this.name = null
- }
- }
- /* Printer class */
- Brain4it.Printer = function() {
- this.output = null
- this.cursorStack = null
- this.dataRegistry = null
- this.structureRegistry = null
- this.addSpace = true
- this.anchorCount = 0
- }
- Brain4it.Printer.prototype = {
- print: function(object) {
- this.createAnchorMap(object)
- this.cursorStack = []
- this.output = []
- if (object instanceof Brain4it.List) {
- var list = object
- this.writeListStart(this.getTag(list))
- var cursor = new Brain4it.Printer.Cursor(list)
- this.cursorStack.push(cursor)
- while (this.cursorStack.length > 0) {
- cursor = this.cursorStack.pop()
- while (cursor.hasNext()) {
- var name = cursor.getName()
- var element = cursor.getElement()
- cursor.next()
- if (this.addSpace) {
- this.output.push(' ')
- } else {
- this.addSpace = true
- }
- if (name !== null) {
- this.writeName(name)
- }
- if (element instanceof Brain4it.List) {
- list = element
- var tag = this.getTag(list)
- if (tag instanceof Brain4it.LinkTag) {
- this.output.push(tag.toString())
- } else {
- this.cursorStack.push(cursor)
- this.writeListStart(tag)
- cursor = new Brain4it.Printer.Cursor(list)
- }
- } else {
- this.writeNonList(element)
- }
- }
- this.writeListEnd()
- }
- } else {
- this.writeNonList(object)
- }
- return this.output.join('')
- },
- writeName: function(name) {
- this.output.push('"')
- this.output.push(Brain4it.escapeString(name))
- this.output.push('" ')
- this.output.push(Brain4it.NAME_OPERATOR_TOKEN)
- this.output.push(' ')
- },
- writeListStart: function(tag) {
- this.output.push(Brain4it.OPEN_LIST_TOKEN)
- if (tag !== null) {
- this.output.push(tag.toString())
- } else {
- this.addSpace = false
- }
- },
- writeListEnd: function() {
- this.output.push(Brain4it.CLOSE_LIST_TOKEN)
- },
- writeNonList: function(object) {
- if (object instanceof Brain4it.Reference) {
- this.output.push(object.name)
- } else if (typeof object === 'string') {
- this.output.push('"')
- this.output.push(Brain4it.escapeString(object))
- this.output.push('"')
- } else {
- this.output.push(String(object))
- }
- },
- getTag: function(list) {
- var dataAnchor = this.dataRegistry[list.id]
- // dataAnchor can't be null because there are no thread issues.
- if (dataAnchor.declared) return new Brain4it.LinkTag(dataAnchor.getListId())
- var structure = list.getStructure()
- var structureAnchor = structure === null ? null : this.structureRegistry[structure.id]
- var dataListId = dataAnchor.referenceCount > 1 ? dataAnchor.getListId() : null
- var structureListId = structureAnchor !== null && structureAnchor.referenceCount > 1 ? structureAnchor.getListId() : null
- if (dataListId === null && structureListId === null) return null
- dataAnchor.declared = true
- return new Brain4it.DeclarationTag(dataListId, structureListId)
- },
- createAnchorMap: function(baseObject) {
- var list
- var cursor
- this.dataRegistry = {}
- this.structureRegistry = {}
- this.cursorStack = []
- if (baseObject instanceof Brain4it.List) {
- list = baseObject
- this.registerList(list)
- cursor = new Brain4it.Printer.Cursor(list)
- this.cursorStack.push(cursor)
- while (this.cursorStack.length > 0) {
- cursor = this.cursorStack.pop()
- while (cursor.hasNext()) {
- var element = cursor.getElement()
- cursor.next()
- if (element instanceof Brain4it.List) {
- list = element
- if (this.registerList(list)) {
- this.cursorStack.push(cursor)
- cursor = new Brain4it.Printer.Cursor(list)
- }
- }
- }
- }
- }
- },
- registerList: function(list) {
- var dataAnchor = this.dataRegistry[list.id]
- if (dataAnchor === undefined) {
- dataAnchor = new Brain4it.Printer.Anchor(this)
- this.dataRegistry[list.id] = dataAnchor
- var structure = list.getStructure()
- if (structure !== null) {
- var structureAnchor = this.structureRegistry[structure.id]
- if (structureAnchor === undefined) {
- this.structureRegistry[structure.id] = dataAnchor
- } else {
- structureAnchor.referenceCount++
- }
- }
- return true
- } else {
- dataAnchor.referenceCount++
- return false
- }
- }
- }
- Brain4it.Printer.Anchor = function(printer) {
- this.printer = printer
- this.listId = 0
- this.referenceCount = 1
- this.declared = false
- }
- Brain4it.Printer.Anchor.prototype = {
- getListId: function() {
- if (this.listId === 0) {
- this.listId = String(++this.printer.anchorCount)
- }
- return this.listId
- },
- toString: function() {
- return this.listId + '/' + this.referenceCount
- }
- }
- Brain4it.Printer.Cursor = function(list) {
- this.list = list
- this.index = 0
- }
- Brain4it.Printer.Cursor.prototype = {
- hasNext: function() {
- return this.index < this.list.size()
- },
- next: function() {
- this.index++
- },
- getName: function() {
- return this.list.getName(this.index)
- },
- getElement: function() {
- return this.list.getByIndex(this.index)
- }
- }
- /* Formatter class */
- Brain4it.Formatter = function(configuration) {
- this.configuration = configuration || new Brain4it.Formatter.Configuration()
- this.output = null
- this.tokenizer = null
- this.baseList = null
- this.currentList = null
- this.indentLevel = 0
- this.written = false
- this.name = null
- }
- Brain4it.Formatter.prototype = {
- format: function(code) {
- this.output = []
- this.tokenizer = new Brain4it.Tokenizer(code)
- this.baseList = null
- this.currentList = null
- this.indentLevel = 0
- this.written = false
- this.name = null
- var inline = false
- var token
- var end = false
- while (!end) {
- token = this.tokenizer.readToken()
- if (token.type === Brain4it.Token.EOF) {
- if (this.baseList !== null) {
- this.baseList.print()
- }
- end = true
- } else if (inline) {
- this.addToken(token)
- if (this.currentList === null) {
- // baseList closed
- if (this.name === null) {
- this.nextLine()
- } else {
- this.printSpace()
- }
- this.baseList.print()
- this.baseList = null
- this.name = null
- inline = false
- } else if (this.isBreakRequired()) {
- if (this.name === null || this.indentLevel * this.configuration.indentSize + this.baseList.getLength() > this.configuration.maxColumns) {
- this.baseList.releaseExcedent()
- this.nextLine()
- this.baseList.print()
- this.baseList = null
- this.currentList = null
- this.indentLevel++
- inline = false
- }
- // else try to print baseList inline in the next line
- this.name = null
- }
- } // !inline: tokens in vertical
- else {
- if (token.type === Brain4it.Token.OPEN_LIST) {
- this.baseList = new Brain4it.Formatter.TokenList(this, token)
- this.currentList = this.baseList
- inline = true
- } else if (token.type === Brain4it.Token.CLOSE_LIST) {
- this.indentLevel--
- this.nextLine()
- this.printToken(token)
- } else {
- this.nextLine()
- this.printToken(token)
- var nextToken = this.tokenizer.readToken()
- if (nextToken.type === Brain4it.Token.NAME_OPERATOR) {
- this.name = String(token.text)
- this.printSpace()
- this.printToken(nextToken) // name operator
- var nextNextToken = this.tokenizer.readToken()
- if (nextNextToken.type !== Brain4it.Token.OPEN_LIST && nextNextToken.type !== Brain4it.Token.EOF) {
- if (this.getCurrentColumn() + 1 + nextNextToken.length() > this.configuration.maxColumns) {
- this.nextLine()
- } else {
- this.printSpace()
- }
- this.printToken(nextNextToken)
- this.name = null
- } else this.tokenizer.unreadToken(nextNextToken)
- } else this.tokenizer.unreadToken(nextToken)
- }
- }
- }
- return this.output.join('')
- },
- addToken: function(token) {
- if (token.type === Brain4it.Token.OPEN_LIST) {
- var tokenList = new Brain4it.Formatter.TokenList(this, token, this.currentList)
- this.currentList.add(tokenList)
- this.currentList = tokenList
- } else if (token.type === Brain4it.Token.CLOSE_LIST) {
- this.currentList.add(token)
- this.currentList = this.currentList.parent
- } else {
- this.currentList.add(token)
- }
- },
- getCurrentColumn: function() {
- var column = this.indentLevel * this.configuration.indentSize
- if (this.name !== null) column += this.name.length + Brain4it.NAME_OPERATOR_TOKEN.length + 2
- return column
- },
- isBreakRequired: function() {
- var configuration = this.configuration
- // check is maxColumn is exceeded
- if (this.getCurrentColumn() + this.baseList.getLength() > configuration.maxColumns) return true
- // check if function is not inline
- var functionName = this.baseList.getFunctionName()
- if (functionName === null) return false
- if (configuration.notInlineFunctions.indexOf(functionName) === -1) return false
- var args = configuration.inlineArguments[functionName]
- if (args === undefined) return true
- return this.baseList.getCompletedArguments() >= args
- },
- nextLine: function() {
- if (this.written) {
- this.printCR()
- for (var i = 0; i < this.indentLevel; i++) {
- this.printIndent(this.configuration.indentSize)
- }
- }
- },
- printToken: function(token) {
- this.output.push(token.text)
- this.written = true
- },
- printCR: function() {
- this.output.push('\n')
- },
- printIndent: function(indentSize) {
- for (var i = 0; i < indentSize; i++) {
- this.output.push(' ')
- }
- },
- printSpace: function() {
- this.output.push(' ')
- }
- }
- Brain4it.Formatter.TokenList = function(formatter, openToken, parent) {
- this.formatter = formatter
- this.elements = [openToken]
- this.parent = parent || null
- }
- Brain4it.Formatter.TokenList.prototype = {
- releaseExcedent: function() {
- var configuration = this.formatter.configuration
- var functionName = this.getFunctionName()
- if (functionName === null) {
- this.unreadTokens(1)
- } else {
- var args = configuration.inlineArguments[functionName]
- if (args === undefined) {
- this.unreadTokens(2)
- } else {
- if (this.getCompletedArguments() >= args) {
- var count = args + 2
- if (this.getLength(count) < configuration.maxColumns) {
- this.unreadTokens(count)
- } else {
- this.unreadTokens(2)
- }
- } else {
- this.unreadTokens(2)
- }
- }
- }
- },
- add: function(elem) {
- this.elements.push(elem)
- },
- unreadTokens: function(tokensLeft) {
- for (var i = this.elements.length - 1; i >= tokensLeft; i--) {
- var elem = this.elements[i]
- if (elem instanceof Brain4it.Token) {
- var token = elem
- this.formatter.tokenizer.unreadToken(token)
- } // TokenList
- else {
- var tokenList = elem
- tokenList.unreadTokens(0)
- }
- this.elements.pop()
- }
- },
- isClosed: function() {
- var size = this.elements.length
- var last = this.elements[size - 1]
- if (last instanceof Brain4it.Token) {
- var token = last
- return token.type === Brain4it.Token.CLOSE_LIST
- }
- return false
- },
- getCompletedArguments: function() {
- var size = this.elements.length
- var last = this.elements[size - 1]
- if (last instanceof Brain4it.Token) {
- var token = last
- return token.type === Brain4it.Token.CLOSE_LIST ? size - 3 : size - 2
- } // TokenList
- else {
- var tokenList = last
- return tokenList.isClosed() ? size - 2 : size - 3
- }
- },
- getLength: function(count) {
- count = count || this.elements.length
- var length = 0
- for (var i = 0; i < count; i++) {
- var elem = this.elements[i]
- if (i > 1 && !(elem instanceof Brain4it.Token && elem.type === Brain4it.Token.CLOSE_LIST)) {
- length++ // space
- }
- if (elem instanceof Brain4it.Token) {
- var token = elem
- length += token.length()
- } // TokenList
- else {
- var tokenList = elem
- length += tokenList.getLength()
- }
- }
- return length
- },
- print: function() {
- for (var i = 0; i < this.elements.length; i++) {
- var elem = this.elements[i]
- if (i > 1 && !(elem instanceof Brain4it.Token && elem.type === Brain4it.Token.CLOSE_LIST)) {
- this.formatter.printSpace()
- }
- if (elem instanceof Brain4it.Token) {
- var token = elem
- this.formatter.printToken(token)
- } // TokenList
- else {
- var tokenList = elem
- tokenList.print()
- }
- }
- },
- getFunctionName: function() {
- if (this.elements.length < 2) return null
- var elem = this.elements[1]
- if (!(elem instanceof Brain4it.Token)) return null
- var token = elem
- if (token.type !== Brain4it.Token.REFERENCE) return null
- if (this.elements.length >= 3) {
- // test reference is not a name
- elem = this.elements[2]
- if (elem instanceof Brain4it.Token) {
- var token2 = elem
- if (token2.type === Brain4it.Token.NAME_OPERATOR) return null
- }
- }
- return token.text
- }
- }
- Brain4it.Formatter.Configuration = function(indentSize, maxColumns, notInlineFunctions, inlineArguments) {
- this.indentSize = indentSize || 2
- this.maxColumns = maxColumns || 60
- this.notInlineFunctions = notInlineFunctions || ['do', 'cond', 'for', 'when', 'while']
- this.inlineArguments = inlineArguments || {
- function: 1,
- if: 1,
- set: 1,
- when: 1,
- while: 1,
- for: 3,
- 'for-each': 2,
- apply: 2,
- find: 2,
- sync: 1
- }
- }
- /* Client class */
- Brain4it.Client = function(serverUrl, path, accessKey, sessionId) {
- this.serverUrl = serverUrl
- this.path = path
- this.accessKey = accessKey || null
- this.sessionId = sessionId || null
- this.method = 'POST'
- this.request = new XMLHttpRequest()
- this.callback = null
- }
- Brain4it.Client.prototype = {
- send: function(data) {
- var scope = this
- var request = this.request
- if (request.readyState > 0) request.abort()
- var path = this.path === null ? '' : '/' + escape(this.path)
- request.open(this.method, this.serverUrl + path, true)
- if (this.accessKey) {
- request.setRequestHeader(Brain4it.ACCESS_KEY_HEADER, this.accessKey)
- }
- if (this.sessionId) {
- request.setRequestHeader(Brain4it.SESSION_ID_HEADER, this.sessionId)
- }
- if (data) {
- request.setRequestHeader('Content-Type', Brain4it.MIMETYPE + '; charset=' + Brain4it.CHARSET)
- }
- request.onreadystatechange = function() {
- if (request.readyState === 4) {
- if (scope.callback) {
- var value = request.getResponseHeader(Brain4it.SERVER_TIME_HEADER)
- var serverTime = value === null ? 0 : parseFloat(value)
- scope.callback(request.status, request.responseText, serverTime)
- }
- }
- }
- request.send(data)
- },
- abort: function() {
- if (this.request) {
- this.request.abort()
- }
- }
- }
- /* Monitor class */
- Brain4it.Monitor = function(serverUrl, module, accessKey, sessionId) {
- this.url = serverUrl + '/' + escape(module)
- this.accessKey = accessKey
- this.sessionId = sessionId || null
- this.listeners = {}
- this.watchRequest = new XMLHttpRequest()
- this.connectionDelay = 100
- this.pollingInterval = 0
- this.timerId = null
- this.monitorSessionId = null
- }
- Brain4it.Monitor.prototype = {
- watch: function(functionName, listener) {
- if (functionName === undefined || functionName === null) return
- var functionListeners = this.listeners[functionName]
- if (functionListeners === undefined) {
- functionListeners = [listener]
- this.listeners[functionName] = functionListeners
- } else {
- if (functionListeners.indexOf(listener) === -1) {
- functionListeners.push(listener)
- }
- }
- var scope = this
- if (this.timerId !== null) {
- // delayed start
- clearTimeout(this.timerId)
- }
- this.timerId = setTimeout(function() {
- scope.sendWatchRequest()
- }, this.connectionDelay)
- },
- unwatch: function(functionName, listener) {
- var functionListeners = this.listeners[functionName]
- if (functionListeners) {
- var index = functionListeners.indexOf(listener)
- if (index !== -1) {
- functionListeners.splice(index, 1)
- if (functionListeners.length === 0) {
- delete this.listeners[functionName]
- }
- }
- }
- this.sendWatchRequest()
- },
- unwatchAll: function(sync) {
- this.listeners = {}
- var watchRequest = this.watchRequest
- if (watchRequest.readyState !== 0 && watchRequest.readyState !== 4) {
- // request in progress
- watchRequest.abort()
- this.sendUnwatchRequest(sync)
- }
- },
- sendWatchRequest: function() {
- var scope = this
- var watchRequest = this.watchRequest
- if (watchRequest.readyState !== 0 && watchRequest.readyState !== 4) {
- // cancel request in progress
- watchRequest.abort()
- this.sendUnwatchRequest()
- }
- var list = new Brain4it.List()
- for (var functionName in this.listeners) {
- list.add(functionName)
- }
- if (list.size() === 0) return // Monitor is idle, so exit
- watchRequest.open('POST', this.url, true)
- watchRequest.setRequestHeader('Content-Type', Brain4it.MIMETYPE + '; charset=' + Brain4it.CHARSET)
- var pollingInterval = 0
- if (typeof this.pollingInterval === 'number') {
- if (this.pollingInterval > 0) {
- pollingInterval = this.pollingInterval
- }
- }
- watchRequest.setRequestHeader(Brain4it.MONITOR_HEADER, String(pollingInterval))
- if (this.accessKey) {
- watchRequest.setRequestHeader(Brain4it.ACCESS_KEY_HEADER, this.accessKey)
- }
- if (this.sessionId) {
- watchRequest.setRequestHeader(Brain4it.SESSION_ID_HEADER, this.sessionId)
- }
- var index = 0
- watchRequest.onprogress = function() {
- var response = watchRequest.response
- var chunkEnd = response.indexOf('\n', index)
- while (chunkEnd !== -1) {
- var chunk = response.substring(index, chunkEnd)
- scope.processChunk(chunk)
- index = chunkEnd + 1
- chunkEnd = response.indexOf('\n', index)
- }
- }
- watchRequest.onreadystatechange = function(event) {
- if (watchRequest.readyState === 4) {
- console.info('request terminated')
- scope.sendWatchRequest()
- }
- }
- var printer = new Brain4it.Printer()
- var functionNames = printer.print(list)
- console.info(functionNames)
- watchRequest.send(functionNames)
- },
- sendUnwatchRequest: function(sync) {
- if (this.monitorSessionId) {
- if (typeof sync === 'undefined') sync = false
- var unwatchRequest = new XMLHttpRequest()
- unwatchRequest.open('POST', this.url, !sync)
- unwatchRequest.setRequestHeader('Content-Type', Brain4it.MIMETYPE + '; charset=' + Brain4it.CHARSET)
- unwatchRequest.setRequestHeader(Brain4it.MONITOR_HEADER, '0')
- unwatchRequest.send('"' + this.monitorSessionId + '"')
- console.info('unwatch request sent ' + this.monitorSessionId + ' ' + sync)
- this.monitorSessionId = null
- }
- },
- processChunk: function(chunk) {
- try {
- var parser = new Brain4it.Parser()
- var change = parser.parse(chunk)
- if (change instanceof Brain4it.List) {
- var functionName = change.getByIndex(0)
- var value = change.getByIndex(1)
- var serverTime = change.size() < 3 ? 0 : change.getByIndex(2)
- if (typeof serverTime !== 'number') serverTime = 0
- var functionListeners = this.listeners[functionName]
- if (functionListeners) {
- for (var i = 0; i < functionListeners.length; i++) {
- functionListeners[i](functionName, value, serverTime)
- }
- }
- } else if (typeof change === 'string') {
- this.monitorSessionId = change
- }
- } catch (ex) {
- // Ignore
- }
- }
- }
- /* Invoker class */
- Brain4it.Invoker = function(client, moduleName) {
- this.client = client
- this.moduleName = moduleName
- this.queue = []
- this.sending = false
- }
- Brain4it.Invoker.prototype = {
- invoke: function(functionName, value, coalesce, callback) {
- if (typeof functionName !== 'string') throw 'functionName is required'
- var found = false
- if (coalesce && callback !== null) {
- // update value of call from the same callback
- var i = 0
- while (i < this.queue.length && !found) {
- var call = this.queue[i]
- if (callback === call.callback) {
- call.value = value // set next value to send
- found = true
- }
- i++
- }
- }
- if (!found) {
- // add new call to queue
- var call = {
- functionName: functionName,
- value: value,
- callback: callback
- }
- this.queue.push(call)
- }
- this.internalInvoke()
- return !found
- },
- internalInvoke: function() {
- if (this.sending) return
- var call = this.queue.shift()
- if (call) {
- var functionName = call.functionName
- var value = call.value
- var valueString
- if (typeof value === 'string') {
- valueString = '"' + Brain4it.escapeString(value) + '"'
- } else {
- var printer = new Brain4it.Printer()
- valueString = printer.print(value)
- }
- var client = this.client
- var scope = this
- client.method = 'POST'
- client.path = this.moduleName + '/' + functionName
- client.callback = function(status, resultString, serverTime) {
- if (call.callback) {
- call.callback(status, resultString, serverTime)
- }
- scope.sending = false
- scope.internalInvoke()
- }
- scope.sending = true
- client.send(valueString)
- }
- }
- }
- Brain4it.FunctionInvoker = function(invoker, functionName, invokeInterval) {
- this.invoker = invoker
- this.functionName = functionName
- this.invokeInterval = invokeInterval || 0
- this.invokeTime = 0
- this.sending = 0
- this.nextValue = null
- this.timerId = null
- var scope = this
- this.callback = function(status, resultString, serverTime) {
- scope.sending--
- scope.invokeTime = serverTime
- }
- }
- Brain4it.FunctionInvoker.prototype = {
- invoke: function(value) {
- if (this.invokeInterval === 0) {
- if (this.invoker.invoke(this.functionName, value, true, this.callback)) {
- this.sending++
- }
- } else {
- this.nextValue = value
- this.internalInvoke()
- }
- },
- isSending: function() {
- return this.sending > 0 || this.nextValue !== null
- },
- updateInvokeTime: function(serverTime) {
- if (serverTime > this.invokeTime) {
- this.invokeTime = serverTime
- return true
- }
- return false
- },
- internalInvoke: function() {
- if (this.timerId) return // internalInvoke will be called soon by timer
- if (this.nextValue === null) return
- var value = this.nextValue
- this.nextValue = null
- if (this.invoker.invoke(this.functionName, value, true, this.callback)) {
- this.sending++
- }
- var scope = this
- this.timerId = setTimeout(function() {
- scope.timerId = null
- scope.internalInvoke()
- }, this.invokeInterval)
- }
- }
- /* Helper class */
- Brain4it.Helper = function(serverUrl, module, accessKey) {
- this.functions = []
- this.functionsMap = {}
- this.serverUrl = serverUrl
- this.module = module
- this.accessKey = accessKey
- }
- Brain4it.Helper.prototype = {
- LOAD_FUNCTIONS: '(functions)',
- loadFunctions: function(callback) {
- var scope = this
- var client = new Brain4it.Client(this.serverUrl, this.module, this.accessKey)
- client.method = 'POST'
- client.callback = function(status, output) {
- if (status === 200) {
- var parser = new Brain4it.Parser()
- var object = parser.parse(output)
- if (object instanceof Brain4it.List) {
- scope.functions = []
- scope.functionsMap = {}
- for (var i = 0; i < object.size(); i++) {
- var functionReference = object.getByIndex(i)
- var functionName = functionReference.name
- scope.functions.push(functionName)
- scope.functionsMap[functionName] = true
- }
- }
- }
- if (callback) {
- callback(scope.functions, output)
- }
- }
- client.send(this.LOAD_FUNCTIONS)
- },
- isFunction: function(name) {
- return this.functionsMap.propertyIsEnumerable(name)
- }
- }
- export { Brain4it }
|