ansible/MIKROTIK/cp/JParser

347 lines
14 KiB
Plaintext
Raw Normal View History

2025-10-31 08:47:26 +04:00
/system script add dont-require-permissions=no name=JParser owner=akhmetzyanovrr policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="# ------------------------------\
-- JParseFunctions ---------------------------------------------------\r\
\n# ------------------------------- fJParsePrint ----------------------------------------------------------------\r\
\n:global fJParsePrint\r\
\n:if (!any \$fJParsePrint) do={ :global fJParsePrint do={\r\
\n :global JParseOut\r\
\n :local TempPath\r\
\n :global fJParsePrint\r\
\n\r\
\n :if ([:len \$1] = 0) do={\r\
\n :set \$1 \"\\\$JParseOut\"\r\
\n :set \$2 \$JParseOut\r\
\n }\r\
\n \r\
\n :foreach k,v in=\$2 do={\r\
\n :if ([:typeof \$k] = \"str\") do={\r\
\n :set k \"\\\"\$k\\\"\"\r\
\n }\r\
\n :set TempPath (\$1. \"->\" . \$k)\r\
\n :if ([:typeof \$v] = \"array\") do={\r\
\n :if ([:len \$v] > 0) do={\r\
\n \$fJParsePrint \$TempPath \$v\r\
\n } else={\r\
\n :put \"\$TempPath = [] (\$[:typeof \$v])\"\r\
\n }\r\
\n } else={\r\
\n :put \"\$TempPath = \$v (\$[:typeof \$v])\"\r\
\n }\r\
\n }\r\
\n}}\r\
\n# ------------------------------- fJParsePrintVar ----------------------------------------------------------------\r\
\n:global fJParsePrintVar\r\
\n:if (!any \$fJParsePrintVar) do={ :global fJParsePrintVar do={\r\
\n :global JParseOut\r\
\n :local TempPath\r\
\n :global fJParsePrintVar\r\
\n :local fJParsePrintRet \"\"\r\
\n\r\
\n :if ([:len \$1] = 0) do={\r\
\n :set \$1 \"\\\$JParseOut\"\r\
\n :set \$2 \$JParseOut\r\
\n }\r\
\n \r\
\n :foreach k,v in=\$2 do={\r\
\n :if ([:typeof \$k] = \"str\") do={\r\
\n :set k \"\\\"\$k\\\"\"\r\
\n }\r\
\n :set TempPath (\$1. \"->\" . \$k)\r\
\n :if (\$fJParsePrintRet != \"\") do={\r\
\n :set fJParsePrintRet (\$fJParsePrintRet . \"\\r\\n\")\r\
\n } \r\
\n :if ([:typeof \$v] = \"array\") do={\r\
\n :if ([:len \$v] > 0) do={\r\
\n :set fJParsePrintRet (\$fJParsePrintRet . [\$fJParsePrintVar \$TempPath \$v])\r\
\n } else={\r\
\n :set fJParsePrintRet (\$fJParsePrintRet . \"\$TempPath = [] (\$[:typeof \$v])\")\r\
\n }\r\
\n } else={\r\
\n :set fJParsePrintRet (\$fJParsePrintRet . \"\$TempPath = \$v (\$[:typeof \$v])\")\r\
\n }\r\
\n }\r\
\n :return \$fJParsePrintRet\r\
\n}}\r\
\n# ------------------------------- fJSkipWhitespace ----------------------------------------------------------------\r\
\n:global fJSkipWhitespace\r\
\n:if (!any \$fJSkipWhitespace) do={ :global fJSkipWhitespace do={\r\
\n :global Jpos\r\
\n :global JSONIn\r\
\n :global Jdebug\r\
\n :while (\$Jpos < [:len \$JSONIn] and ([:pick \$JSONIn \$Jpos] ~ \"[ \\r\\n\\t]\")) do={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n }\r\
\n :if (\$Jdebug) do={:put \"fJSkipWhitespace: Jpos=\$Jpos Char=\$[:pick \$JSONIn \$Jpos]\"}\r\
\n}}\r\
\n# -------------------------------- fJParse ---------------------------------------------------------------\r\
\n:global fJParse\r\
\n:if (!any \$fJParse) do={ :global fJParse do={\r\
\n :global Jpos\r\
\n :global JSONIn\r\
\n :global Jdebug\r\
\n :global fJSkipWhitespace\r\
\n :local Char\r\
\n\r\
\n :if (!\$1) do={\r\
\n :set Jpos 0\r\
\n }\r\
\n \r\
\n \$fJSkipWhitespace\r\
\n :set Char [:pick \$JSONIn \$Jpos]\r\
\n :if (\$Jdebug) do={:put \"fJParse: Jpos=\$Jpos Char=\$Char\"}\r\
\n :if (\$Char=\"{\") do={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n :global fJParseObject\r\
\n :return [\$fJParseObject]\r\
\n } else={\r\
\n :if (\$Char=\"[\") do={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n :global fJParseArray\r\
\n :return [\$fJParseArray]\r\
\n } else={\r\
\n :if (\$Char=\"\\\"\") do={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n :global fJParseString\r\
\n :return [\$fJParseString]\r\
\n } else={\r\
\n# :if ([:pick \$JSONIn \$Jpos (\$Jpos+2)]~\"^-\\\?[0-9]\") do={\r\
\n :if (\$Char~\"[eE0-9.+-]\") do={\r\
\n :global fJParseNumber\r\
\n :return [\$fJParseNumber]\r\
\n } else={\r\
\n\r\
\n :if (\$Char=\"n\" and [:pick \$JSONIn \$Jpos (\$Jpos+4)]=\"null\") do={\r\
\n :set Jpos (\$Jpos + 4)\r\
\n :return []\r\
\n } else={\r\
\n :if (\$Char=\"t\" and [:pick \$JSONIn \$Jpos (\$Jpos+4)]=\"true\") do={\r\
\n :set Jpos (\$Jpos + 4)\r\
\n :return true\r\
\n } else={\r\
\n :if (\$Char=\"f\" and [:pick \$JSONIn \$Jpos (\$Jpos+5)]=\"false\") do={\r\
\n :set Jpos (\$Jpos + 5)\r\
\n :return false\r\
\n } else={\r\
\n :put \"Err.Raise 8732. No JSON object could be fJParseed\"\r\
\n :set Jpos (\$Jpos + 1)\r\
\n :return []\r\
\n }\r\
\n }\r\
\n }\r\
\n }\r\
\n }\r\
\n }\r\
\n }\r\
\n}}\r\
\n\r\
\n#-------------------------------- fJParseString ---------------------------------------------------------------\r\
\n:global fJParseString\r\
\n:if (!any \$fJParseString) do={ :global fJParseString do={\r\
\n :global Jpos\r\
\n :global JSONIn\r\
\n :global Jdebug\r\
\n :global fUnicodeToUTF8\r\
\n :local Char\r\
\n :local StartIdx\r\
\n :local Char2\r\
\n :local TempString \"\"\r\
\n :local UTFCode\r\
\n :local Unicode\r\
\n\r\
\n :set StartIdx \$Jpos\r\
\n :set Char [:pick \$JSONIn \$Jpos]\r\
\n :if (\$Jdebug) do={:put \"fJParseString: Jpos=\$Jpos Char=\$Char\"}\r\
\n :while (\$Jpos < [:len \$JSONIn] and \$Char != \"\\\"\") do={\r\
\n :if (\$Char=\"\\\\\") do={\r\
\n :set Char2 [:pick \$JSONIn (\$Jpos + 1)]\r\
\n :if (\$Char2 = \"u\") do={\r\
\n :set UTFCode [:tonum \"0x\$[:pick \$JSONIn (\$Jpos+2) (\$Jpos+6)]\"]\r\
\n :if (\$UTFCode>=0xD800 and \$UTFCode<=0xDFFF) do={\r\
\n# Surrogate pair\r\
\n :set Unicode ((\$UTFCode & 0x3FF) << 10)\r\
\n :set UTFCode [:tonum \"0x\$[:pick \$JSONIn (\$Jpos+8) (\$Jpos+12)]\"]\r\
\n :set Unicode (\$Unicode | (\$UTFCode & 0x3FF) | 0x10000)\r\
\n :set TempString (\$TempString . [:pick \$JSONIn \$StartIdx \$Jpos] . [\$fUnicodeToUTF8 \$Unicode]) \r\
\n :set Jpos (\$Jpos + 12)\r\
\n } else= {\r\
\n# Basic Multilingual Plane (BMP)\r\
\n :set Unicode \$UTFCode\r\
\n :set TempString (\$TempString . [:pick \$JSONIn \$StartIdx \$Jpos] . [\$fUnicodeToUTF8 \$Unicode])\r\
\n :set Jpos (\$Jpos + 6)\r\
\n }\r\
\n :set StartIdx \$Jpos\r\
\n :if (\$Jdebug) do={:put \"fJParseString Unicode: \$Unicode\"}\r\
\n } else={\r\
\n :if (\$Char2 ~ \"[\\\\bfnrt\\\"]\") do={\r\
\n :if (\$Jdebug) do={:put \"fJParseString escape: Char+Char2 \$Char\$Char2\"}\r\
\n :set TempString (\$TempString . [:pick \$JSONIn \$StartIdx \$Jpos] . [[:parse \"(\\\"\\\\\$Char2\\\")\"]])\r\
\n :set Jpos (\$Jpos + 2)\r\
\n :set StartIdx \$Jpos\r\
\n } else={\r\
\n :if (\$Char2 = \"/\") do={\r\
\n :if (\$Jdebug) do={:put \"fJParseString /: Char+Char2 \$Char\$Char2\"}\r\
\n :set TempString (\$TempString . [:pick \$JSONIn \$StartIdx \$Jpos] . \"/\")\r\
\n :set Jpos (\$Jpos + 2)\r\
\n :set StartIdx \$Jpos\r\
\n } else={\r\
\n :put \"Err.Raise 8732. Invalid escape\"\r\
\n :set Jpos (\$Jpos + 2)\r\
\n }\r\
\n }\r\
\n }\r\
\n } else={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n }\r\
\n :set Char [:pick \$JSONIn \$Jpos]\r\
\n }\r\
\n :set TempString (\$TempString . [:pick \$JSONIn \$StartIdx \$Jpos])\r\
\n :set Jpos (\$Jpos + 1)\r\
\n :if (\$Jdebug) do={:put \"fJParseString: \$TempString\"}\r\
\n :return \$TempString\r\
\n}}\r\
\n\r\
\n#-------------------------------- fJParseNumber ---------------------------------------------------------------\r\
\n:global fJParseNumber\r\
\n:if (!any \$fJParseNumber) do={ :global fJParseNumber do={\r\
\n :global Jpos\r\
\n :local StartIdx\r\
\n :global JSONIn\r\
\n :global Jdebug\r\
\n :local NumberString\r\
\n :local Number\r\
\n\r\
\n :set StartIdx \$Jpos \r\
\n :set Jpos (\$Jpos + 1)\r\
\n :while (\$Jpos < [:len \$JSONIn] and [:pick \$JSONIn \$Jpos]~\"[eE0-9.+-]\") do={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n }\r\
\n :set NumberString [:pick \$JSONIn \$StartIdx \$Jpos]\r\
\n :set Number [:tonum \$NumberString]\r\
\n :if ([:typeof \$Number] = \"num\") do={\r\
\n :if (\$Jdebug) do={:put \"fJParseNumber: StartIdx=\$StartIdx Jpos=\$Jpos \$Number (\$[:typeof \$Number])\"}\r\
\n :return \$Number\r\
\n } else={\r\
\n :if (\$Jdebug) do={:put \"fJParseNumber: StartIdx=\$StartIdx Jpos=\$Jpos \$NumberString (\$[:typeof \$NumberString])\"}\r\
\n :return \$NumberString\r\
\n }\r\
\n}}\r\
\n\r\
\n#-------------------------------- fJParseArray ---------------------------------------------------------------\r\
\n:global fJParseArray\r\
\n:if (!any \$fJParseArray) do={ :global fJParseArray do={\r\
\n :global Jpos\r\
\n :global JSONIn\r\
\n :global Jdebug\r\
\n :global fJParse\r\
\n :global fJSkipWhitespace\r\
\n :local Value\r\
\n :local ParseArrayRet [:toarray \"\"]\r\
\n \r\
\n \$fJSkipWhitespace \r\
\n :while (\$Jpos < [:len \$JSONIn] and [:pick \$JSONIn \$Jpos]!= \"]\") do={\r\
\n :set Value [\$fJParse true]\r\
\n :set (\$ParseArrayRet->([:len \$ParseArrayRet])) \$Value\r\
\n :if (\$Jdebug) do={:put \"fJParseArray: Value=\"; :put \$Value}\r\
\n \$fJSkipWhitespace\r\
\n :if ([:pick \$JSONIn \$Jpos] = \",\") do={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n \$fJSkipWhitespace\r\
\n }\r\
\n }\r\
\n :set Jpos (\$Jpos + 1)\r\
\n# :if (\$Jdebug) do={:put \"ParseArrayRet: \"; :put \$ParseArrayRet}\r\
\n :return \$ParseArrayRet\r\
\n}}\r\
\n\r\
\n# -------------------------------- fJParseObject ---------------------------------------------------------------\r\
\n:global fJParseObject\r\
\n:if (!any \$fJParseObject) do={ :global fJParseObject do={\r\
\n :global Jpos\r\
\n :global JSONIn\r\
\n :global Jdebug\r\
\n :global fJSkipWhitespace\r\
\n :global fJParseString\r\
\n :global fJParse\r\
\n# Syntax :local ParseObjectRet ({}) don't work in recursive call, use [:toarray \"\"] for empty array!!!\r\
\n :local ParseObjectRet [:toarray \"\"]\r\
\n :local Key\r\
\n :local Value\r\
\n :local ExitDo false\r\
\n \r\
\n \$fJSkipWhitespace\r\
\n :while (\$Jpos < [:len \$JSONIn] and [:pick \$JSONIn \$Jpos]!=\"}\" and !\$ExitDo) do={\r\
\n :if ([:pick \$JSONIn \$Jpos]!=\"\\\"\") do={\r\
\n :put \"Err.Raise 8732. Expecting property name\"\r\
\n :set ExitDo true\r\
\n } else={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n :set Key [\$fJParseString]\r\
\n \$fJSkipWhitespace\r\
\n :if ([:pick \$JSONIn \$Jpos] != \":\") do={\r\
\n :put \"Err.Raise 8732. Expecting : delimiter\"\r\
\n :set ExitDo true\r\
\n } else={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n :set Value [\$fJParse true]\r\
\n :set (\$ParseObjectRet->\$Key) \$Value\r\
\n :if (\$Jdebug) do={:put \"fJParseObject: Key=\$Key Value=\"; :put \$Value}\r\
\n \$fJSkipWhitespace\r\
\n :if ([:pick \$JSONIn \$Jpos]=\",\") do={\r\
\n :set Jpos (\$Jpos + 1)\r\
\n \$fJSkipWhitespace\r\
\n }\r\
\n }\r\
\n }\r\
\n }\r\
\n :set Jpos (\$Jpos + 1)\r\
\n# :if (\$Jdebug) do={:put \"ParseObjectRet: \"; :put \$ParseObjectRet}\r\
\n :return \$ParseObjectRet\r\
\n}}\r\
\n\r\
\n# ------------------- fByteToEscapeChar ----------------------\r\
\n:global fByteToEscapeChar\r\
\n:if (!any \$fByteToEscapeChar) do={ :global fByteToEscapeChar do={\r\
\n# :set \$1 [:tonum \$1]\r\
\n :return [[:parse \"(\\\"\\\\\$[:pick \"0123456789ABCDEF\" ((\$1 >> 4) & 0xF)]\$[:pick \"0123456789ABCDEF\" (\$1 & 0xF)]\\\")\"]]\r\
\n}}\r\
\n\r\
\n# ------------------- fUnicodeToUTF8----------------------\r\
\n:global fUnicodeToUTF8\r\
\n:if (!any \$fUnicodeToUTF8) do={ :global fUnicodeToUTF8 do={\r\
\n :global fByteToEscapeChar\r\
\n# :local Ubytes [:tonum \$1]\r\
\n :local Nbyte\r\
\n :local EscapeStr \"\"\r\
\n\r\
\n :if (\$1 < 0x80) do={\r\
\n :set EscapeStr [\$fByteToEscapeChar \$1]\r\
\n } else={\r\
\n :if (\$1 < 0x800) do={\r\
\n :set Nbyte 2\r\
\n } else={ \r\
\n :if (\$1 < 0x10000) do={\r\
\n :set Nbyte 3\r\
\n } else={\r\
\n :if (\$1 < 0x20000) do={\r\
\n :set Nbyte 4\r\
\n } else={\r\
\n :if (\$1 < 0x4000000) do={\r\
\n :set Nbyte 5\r\
\n } else={\r\
\n :if (\$1 < 0x80000000) do={\r\
\n :set Nbyte 6\r\
\n }\r\
\n }\r\
\n }\r\
\n }\r\
\n }\r\
\n :for i from=2 to=\$Nbyte do={\r\
\n :set EscapeStr ([\$fByteToEscapeChar (\$1 & 0x3F | 0x80)] . \$EscapeStr)\r\
\n :set \$1 (\$1 >> 6)\r\
\n }\r\
\n :set EscapeStr ([\$fByteToEscapeChar (((0xFF00 >> \$Nbyte) & 0xFF) | \$1)] . \$EscapeStr)\r\
\n }\r\
\n :return \$EscapeStr\r\
\n}}\r\
\n\r\
\n# ------------------- End JParseFunctions----------------------"