json.monkey2 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. Namespace std.json
  2. #rem monkeydoc JsonError class.
  3. #end
  4. Class JsonError Extends Throwable
  5. End
  6. #rem monkeydoc JsonValue class.
  7. This is base class of all JsonValue types.
  8. #end
  9. Class JsonValue Abstract
  10. Method ToBool:Bool() Virtual
  11. Assert( False )
  12. Return Null
  13. End
  14. Method ToNumber:Double() Virtual
  15. Assert( False )
  16. Return Null
  17. End
  18. Method ToString:String() Virtual
  19. Assert( False )
  20. Return Null
  21. End
  22. Operator[]:JsonValue( index:Int ) Virtual
  23. Assert( False )
  24. Return Null
  25. End
  26. Operator[]=( index:Int,value:JsonValue ) Virtual
  27. Assert( False )
  28. End
  29. Operator[]:JsonValue( key:String ) Virtual
  30. Assert( False )
  31. Return Null
  32. End
  33. Operator[]=( key:String,value:JsonValue ) Virtual
  34. Assert( False )
  35. End
  36. Method ToJson:String() Virtual
  37. Local buf:=New StringStack
  38. PushJson( buf )
  39. Return buf.Join( "" )
  40. End
  41. Method ToInt:Int()
  42. Return Int( ToNumber() )
  43. End
  44. Method ToLong:Long()
  45. Return Long( ToNumber() )
  46. End
  47. Method ToFloat:Float()
  48. Return Float( ToNumber() )
  49. End
  50. Method ToDouble:Double()
  51. Return ToNumber()
  52. End
  53. Method Save:Bool( path:String )
  54. Local buf:=New StringStack
  55. PushJson( buf )
  56. Local src:=buf.Join( "" )
  57. Return stringio.SaveString( src,path )
  58. End
  59. Function Load:JsonValue( path:String )
  60. Local src:=stringio.LoadString( path )
  61. If Not src Return Null
  62. Local parser:=New JsonParser( src )
  63. Local value:=parser.ParseValue()
  64. Return value
  65. End
  66. Protected
  67. #rem monkeydoc @hidden
  68. #end
  69. Method PushJson:Void( buf:StringStack ) Virtual
  70. buf.Push( ToJson() )
  71. End
  72. End
  73. #rem monkeydoc JsonBool class.
  74. #end
  75. Class JsonBool Extends JsonValue
  76. Const TrueValue:JsonBool=New JsonBool( True )
  77. Const FalseValue:JsonBool=New JsonBool( False )
  78. Method New( data:Bool=False )
  79. _data=data
  80. End
  81. Property Data:Bool()
  82. Return _data
  83. Setter( data:Bool )
  84. _data=data
  85. End
  86. Method ToBool:Bool() Override
  87. Return _data
  88. End
  89. Method ToNumber:Double() Override
  90. Return _data
  91. End
  92. Method ToString:String() Override
  93. Return _data ? "true" Else "false"
  94. End
  95. Method ToJson:String() Override
  96. Return _data ? "true" Else "false"
  97. End
  98. Private
  99. Field _data:Bool
  100. End
  101. #rem monkeydoc JsonNumber class.
  102. #end
  103. Class JsonNumber Extends JsonValue
  104. Method New( data:Double=0 )
  105. _data=data
  106. End
  107. Property Data:Double()
  108. Return _data
  109. Setter( data:Double )
  110. _data=data
  111. End
  112. Method ToBool:Bool() Override
  113. Return _data
  114. End
  115. Method ToNumber:Double() Override
  116. Return _data
  117. End
  118. Method ToString:String() Override
  119. Return _data
  120. End
  121. Method ToJson:String() Override
  122. Return _data
  123. End
  124. Private
  125. Field _data:Double
  126. End
  127. #rem monkeydoc JsonString class.
  128. #end
  129. Class JsonString Extends JsonValue
  130. Method New( data:String="" )
  131. _data=data
  132. End
  133. Property Data:String()
  134. Return _data
  135. Setter( data:String )
  136. _data=data
  137. End
  138. Method ToBool:Bool() Override
  139. Return _data
  140. End
  141. Method ToNumber:Double() Override
  142. Return Double( _data )
  143. End
  144. Method ToString:String() Override
  145. Return _data
  146. End
  147. Method ToJson:String() Override
  148. Return "~q"+_data.Replace( "~q","\~q" )+"~q"
  149. End
  150. Private
  151. Field _data:String
  152. End
  153. #rem monkeydoc JsonArray class.
  154. #end
  155. Class JsonArray Extends JsonValue
  156. Method New( data:Stack<JsonValue> =Null )
  157. If Not data data=New Stack<JsonValue>
  158. _data=data
  159. End
  160. Property Data:Stack<JsonValue>()
  161. Return _data
  162. Setter( data:Stack<JsonValue> )
  163. _data=data
  164. End
  165. Operator[]:JsonValue( index:Int ) Override
  166. Return _data[index]
  167. End
  168. Operator[]=( index:Int,value:JsonValue ) Override
  169. _data[index]=value
  170. End
  171. Private
  172. Field _data:Stack<JsonValue>
  173. Method PushJson:Void( buf:StringStack ) Override
  174. buf.Push( "[" )
  175. Local t:=False
  176. For Local value:=Eachin _data
  177. If t buf.Push( "," )
  178. If value value.PushJson( buf ) Else buf.Push( "null" )
  179. t=True
  180. Next
  181. buf.Push( "]" )
  182. End
  183. End
  184. #rem monkeydoc JsonObject class.
  185. #end
  186. Class JsonObject Extends JsonValue
  187. Method New( data:StringMap<JsonValue> =Null )
  188. If Not data data=New StringMap<JsonValue>
  189. _data=data
  190. End
  191. Property Data:StringMap<JsonValue>()
  192. Return _data
  193. Setter( data:StringMap<JsonValue> )
  194. _data=data
  195. End
  196. Operator[]:JsonValue( key:String ) Override
  197. Return _data[key]
  198. End
  199. Operator[]=( key:String,value:JsonValue ) Override
  200. _data[key]=value
  201. End
  202. Private
  203. Field _data:StringMap<JsonValue>
  204. Method PushJson:Void( buf:StringStack ) Override
  205. buf.Push( "{" )
  206. Local t:=False
  207. For Local it:=Eachin _data
  208. If t buf.Push( "," )
  209. buf.Push( "~q"+it.Key.Replace( "~q","\~q" )+"~q:" )
  210. If it.Value it.Value.PushJson( buf ) Else buf.Push( "null" )
  211. t=True
  212. Next
  213. buf.Push( "}" )
  214. End
  215. End
  216. #rem monkeydoc JsonParser class.
  217. #end
  218. Class JsonParser
  219. Method New( json:String )
  220. _text=json
  221. Bump()
  222. End
  223. Method ParseValue:JsonValue()
  224. If TokeType=T_STRING Return New JsonString( ParseString() )
  225. If TokeType=T_NUMBER Return New JsonNumber( Double( ParseNumber() ) )
  226. If Toke="{" Return New JsonObject( ParseObject() )
  227. If Toke="[" Return New JsonArray( ParseArray() )
  228. If CParse("true") Return JsonBool.TrueValue
  229. If CParse("false") Return JsonBool.FalseValue
  230. If CParse("null") Return Null
  231. Return Null
  232. End
  233. Private
  234. Const T_EOF:=0
  235. Const T_STRING:=1
  236. Const T_NUMBER:=2
  237. Const T_SYMBOL:=3
  238. Const T_IDENT:=4
  239. Field _text:String
  240. Field _toke:String
  241. Field _type:Int
  242. Field _pos:Int
  243. Method GetChar:Int()
  244. If _pos=_text.Length Throw New JsonError()
  245. _pos+=1
  246. Return _text[_pos-1]
  247. End
  248. Method PeekChar:Int()
  249. If _pos=_text.Length Return 0
  250. Return _text[_pos]
  251. End
  252. Method ParseChar:Void( chr:Int )
  253. If _pos>=_text.Length Or _text[_pos]<>chr Throw New JsonError()
  254. _pos+=1
  255. End
  256. Method CParseChar:Bool( chr:Int )
  257. If _pos>=_text.Length Or _text[_pos]<>chr Return False
  258. _pos+=1
  259. Return True
  260. End
  261. Method CParseDigits:Bool()
  262. Local p:=_pos
  263. While _pos<_text.Length And _text[_pos]>=48 And _text[_pos]<=57
  264. _pos+=1
  265. Wend
  266. Return _pos>p
  267. End
  268. Method Bump:String()
  269. While _pos<_text.Length And _text[_pos]<=32
  270. _pos+=1
  271. Wend
  272. If _pos=_text.Length
  273. _toke=""
  274. _type=T_EOF
  275. Return _toke
  276. Endif
  277. Local pos:=_pos
  278. Local chr:=GetChar()
  279. If chr=34
  280. Repeat
  281. Local chr:=GetChar()
  282. If chr=34 Exit
  283. If chr=92 GetChar()
  284. Forever
  285. _type=T_STRING
  286. Else If chr=45 Or (chr>=48 And chr<=57)
  287. If chr=45 '-
  288. chr=GetChar()
  289. If chr<48 Or chr>57 Throw New JsonError()
  290. Endif
  291. If chr<>48 '0
  292. CParseDigits()
  293. End
  294. If CParseChar( 46 ) '.
  295. CParseDigits()
  296. Endif
  297. If CParseChar( 69 ) Or CParseChar( 101 ) 'e E
  298. If PeekChar()=43 Or PeekChar()=45 GetChar() '+ -
  299. If Not CParseDigits() Throw New JsonError()
  300. Endif
  301. _type=T_NUMBER
  302. Else If (chr>=65 And chr<91) Or (chr>=97 And chr<123)
  303. chr=PeekChar()
  304. While (chr>=65 And chr<91) Or (chr>=97 And chr<123)
  305. GetChar()
  306. chr=PeekChar()
  307. Wend
  308. _type=T_IDENT
  309. Else
  310. _type=T_SYMBOL
  311. Endif
  312. _toke=_text.Slice( pos,_pos )
  313. Return _toke
  314. End
  315. Property Toke:String()
  316. Return _toke
  317. End
  318. property TokeType:Int()
  319. Return _type
  320. End
  321. Method CParse:Bool( toke:String )
  322. If toke<>_toke Return False
  323. Bump()
  324. Return True
  325. End
  326. Method Parse:Void( toke:String )
  327. If Not CParse( toke ) Throw New JsonError()
  328. End
  329. Method ParseObject:StringMap<JsonValue>()
  330. Parse( "{" )
  331. Local map:=New StringMap<JsonValue>
  332. If CParse( "}" ) Return map
  333. Repeat
  334. Local name:=ParseString()
  335. Parse( ":" )
  336. Local value:=ParseValue()
  337. map.Set( name,value )
  338. Until Not CParse( "," )
  339. Parse( "}" )
  340. Return map
  341. End
  342. Method ParseArray:Stack<JsonValue>()
  343. Parse( "[" )
  344. If CParse( "]" ) Return Null
  345. Local stack:=New Stack<JsonValue>
  346. Repeat
  347. Local value:=ParseValue()
  348. stack.Push( value )
  349. Until Not CParse( "," )
  350. Parse( "]" )
  351. Return stack
  352. End
  353. Method ParseString:String()
  354. If TokeType<>T_STRING Throw New JsonError()
  355. Local toke:=Toke.Slice( 1,-1 )
  356. Local i:=toke.Find( "\" )
  357. If i<>-1
  358. Local frags:=New StringStack,p:=0,esc:=""
  359. Repeat
  360. If i+1>=toke.Length Throw New JsonError()
  361. frags.Push( toke.Slice( p,i ) )
  362. Select toke[i+1]
  363. Case 34 esc="~q" '\"
  364. Case 92 esc="\" '\\
  365. Case 47 esc="/" '\/
  366. Case 98 esc=String.FromChar( 8 ) '\b
  367. Case 102 esc=String.FromChar( 12 ) '\f
  368. Case 114 esc=String.FromChar( 13 ) '\r
  369. Case 110 esc=String.FromChar( 10 ) '\n
  370. Case 117 '\uxxxx
  371. If i+6>toke.Length Throw New JsonError()
  372. Local val:=0
  373. For Local j:=2 Until 6
  374. Local chr:=toke[i+j]
  375. If chr>=48 And chr<58
  376. val=val Shl 4 | (chr-48)
  377. Else If chr>=65 And chr<123
  378. chr&=31
  379. If chr<1 Or chr>6 Throw New JsonError()
  380. val=val Shl 4 | (chr+9)
  381. Else
  382. Throw New JsonError()
  383. Endif
  384. Next
  385. esc=String.FromChar( val )
  386. i+=4
  387. Default
  388. Throw New JsonError()
  389. End
  390. frags.Push( esc )
  391. p=i+2
  392. i=toke.Find( "\",p )
  393. If i<>-1 Continue
  394. frags.Push( toke.Slice( p ) )
  395. Exit
  396. Forever
  397. toke=frags.Join( "" )
  398. Endif
  399. Bump()
  400. Return toke
  401. End
  402. Method ParseNumber:String()
  403. If TokeType<>T_NUMBER Throw New JsonError()
  404. Local toke:=Toke
  405. Bump()
  406. Return toke
  407. End
  408. End