Load filenames / titles for buttons from json streaming over network. button cli…
…cks load movies on server. timeout started
Showing
26 changed files
with
832 additions
and
29 deletions
No preview for this file type
Assets/StreamingAssets/videoSettings.json
0 → 100644
Assets/_Nest/Prefabs/moviePlayNode.prefab
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
Assets/_Nest/Scripts/AppManager.cs
0 → 100644
| 1 | +using UnityEngine; | ||
| 2 | +using System.Collections; | ||
| 3 | + | ||
| 4 | +public class AppManager : Singleton<AppManager> | ||
| 5 | +{ | ||
| 6 | + public AVProWindowsMediaMovie movieScript; | ||
| 7 | + public Canvas serverCanvas; | ||
| 8 | + public CanvasGroup inactiveCanvas; | ||
| 9 | + public float appTimeout; | ||
| 10 | + | ||
| 11 | + void Start () | ||
| 12 | + { | ||
| 13 | + inactiveCanvas.alpha = 1; | ||
| 14 | + StartCoroutine(AppTimeout()); | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + private bool _videoPlaying = false; | ||
| 18 | + | ||
| 19 | + private IEnumerator AppTimeout() | ||
| 20 | + { | ||
| 21 | + while(true) | ||
| 22 | + { | ||
| 23 | + float timeout = 0; | ||
| 24 | + bool didTimeout = false; | ||
| 25 | + | ||
| 26 | + while (!_videoPlaying) | ||
| 27 | + { | ||
| 28 | + timeout += Time.deltaTime; | ||
| 29 | + print(timeout); | ||
| 30 | + | ||
| 31 | + if (timeout >= appTimeout && ! didTimeout) | ||
| 32 | + { | ||
| 33 | + didTimeout = true; | ||
| 34 | + print("timeout"); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + yield return null; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + yield return null; | ||
| 41 | + } | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public void DestroyServerCanvas() | ||
| 45 | + { | ||
| 46 | + Destroy(serverCanvas.gameObject); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + private Coroutine movieCoroutine; | ||
| 50 | + | ||
| 51 | + public void LoadMovie(string filename) | ||
| 52 | + { | ||
| 53 | + movieScript.UnloadMovie(); | ||
| 54 | + | ||
| 55 | + movieScript._filename = filename; | ||
| 56 | + movieScript.LoadMovie(true); | ||
| 57 | + | ||
| 58 | + TweenCanvasGroup(inactiveCanvas, 0, 1); | ||
| 59 | + | ||
| 60 | + if (movieCoroutine != null) | ||
| 61 | + StopCoroutine(movieCoroutine); | ||
| 62 | + | ||
| 63 | + movieCoroutine = StartCoroutine(MoviePlaying()); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + private IEnumerator MoviePlaying() | ||
| 67 | + { | ||
| 68 | + _videoPlaying = true; | ||
| 69 | + while (movieScript.MovieInstance.IsPlaying) | ||
| 70 | + yield return null; | ||
| 71 | + | ||
| 72 | + _videoPlaying = false; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public void TweenCanvasGroup(CanvasGroup group, float alpha, float time) | ||
| 76 | + { | ||
| 77 | + TweenCanvasGroup(group, alpha, time, null); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + public void TweenCanvasGroup(CanvasGroup group, float alpha, float time, System.Action onComplete) | ||
| 81 | + { | ||
| 82 | + Hashtable hash = new Hashtable() | ||
| 83 | + { | ||
| 84 | + { "from", group.alpha }, | ||
| 85 | + { "to", alpha }, | ||
| 86 | + { "time", time }, | ||
| 87 | + { "onupdate", (System.Action<object>)(x => group.alpha = (float) x) } | ||
| 88 | + }; | ||
| 89 | + | ||
| 90 | + if (onComplete != null) | ||
| 91 | + hash.Add("oncomplete", (System.Action<object>)(x => onComplete())); | ||
| 92 | + | ||
| 93 | + iTween.ValueTo(group.gameObject, hash); | ||
| 94 | + } | ||
| 95 | +} |
Assets/_Nest/Scripts/MovieLoader.cs
deleted
100644 → 0
| 1 | -using UnityEngine; | ||
| 2 | -using System.Collections; | ||
| 3 | - | ||
| 4 | -public class MovieLoader : Singleton<MovieLoader> | ||
| 5 | -{ | ||
| 6 | - public AVProWindowsMediaMovie movieScript; | ||
| 7 | - | ||
| 8 | - void Start () { | ||
| 9 | - | ||
| 10 | - } | ||
| 11 | - | ||
| 12 | - void Update () | ||
| 13 | - { | ||
| 14 | - if (Input.GetKeyDown(KeyCode.Space)) | ||
| 15 | - LoadMovie("sample-1920x1024-divx.avi"); | ||
| 16 | - } | ||
| 17 | - | ||
| 18 | - public void LoadMovie(string filename) | ||
| 19 | - { | ||
| 20 | - movieScript._filename = filename; | ||
| 21 | - movieScript.LoadMovie(true); | ||
| 22 | - } | ||
| 23 | -} |
Assets/_Nest/Scripts/MovieNode.cs
0 → 100644
Assets/_Nest/Scripts/MovieNode.cs.meta
0 → 100644
Assets/_Nest/Scripts/MoviePlayNode.cs
0 → 100644
| 1 | +using UnityEngine; | ||
| 2 | +using System.Collections; | ||
| 3 | +using UnityEngine.UI; | ||
| 4 | + | ||
| 5 | +public class MoviePlayNode : MonoBehaviour | ||
| 6 | +{ | ||
| 7 | + [SerializeField] | ||
| 8 | + private Text _textNode; | ||
| 9 | + private string _filename; | ||
| 10 | + private NetworkUser _netNode; | ||
| 11 | + | ||
| 12 | + public void Initialize(string title, string filename, NetworkUser parent) | ||
| 13 | + { | ||
| 14 | + _textNode.text = title; | ||
| 15 | + _filename = filename; | ||
| 16 | + _netNode = parent; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public void PlayMovie() | ||
| 20 | + { | ||
| 21 | + _netNode.CmdLoadVideo(_filename); | ||
| 22 | + } | ||
| 23 | +} |
Assets/_Nest/Scripts/MoviePlayNode.cs.meta
0 → 100644
| 1 | using UnityEngine; | 1 | using UnityEngine; |
| 2 | using System.Collections; | 2 | using System.Collections; |
| 3 | +using System.Collections.Generic; | ||
| 4 | +using System.IO; | ||
| 3 | using UnityEngine.Networking; | 5 | using UnityEngine.Networking; |
| 4 | 6 | ||
| 5 | public class NetworkUser : NetworkBehaviour | 7 | public class NetworkUser : NetworkBehaviour |
| 6 | { | 8 | { |
| 7 | - void Start () { | 9 | + public Transform buttonParent; |
| 10 | + public MoviePlayNode movieButtonNode; | ||
| 8 | 11 | ||
| 12 | + void Start() | ||
| 13 | + { | ||
| 14 | + if (!isServer) | ||
| 15 | + { | ||
| 16 | + AppManager.Instance.DestroyServerCanvas(); | ||
| 17 | + StartCoroutine(WaitForFiles()); | ||
| 18 | + } | ||
| 19 | + else | ||
| 20 | + { | ||
| 21 | + string path = Application.streamingAssetsPath + "/videoSettings.json"; | ||
| 22 | + if (!File.Exists(path)) | ||
| 23 | + { | ||
| 24 | + Debug.LogError("NetworkUser Error: No videoSettings.json file found"); | ||
| 25 | + return; | ||
| 26 | + } | ||
| 27 | + string json = File.ReadAllText(path); | ||
| 28 | + RpcGetFiles(json); | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public List<Dictionary<string, string>> _files; | ||
| 33 | + | ||
| 34 | + private IEnumerator WaitForFiles() | ||
| 35 | + { | ||
| 36 | + while (_files == null) | ||
| 37 | + yield return null; | ||
| 38 | + | ||
| 39 | + foreach(var dict in _files) | ||
| 40 | + { | ||
| 41 | + MoviePlayNode mpn = Instantiate<MoviePlayNode>(movieButtonNode); | ||
| 42 | + mpn.Initialize(dict["title"], dict["filename"], this); | ||
| 43 | + mpn.transform.SetParent(buttonParent); | ||
| 44 | + mpn.transform.localPosition = Vector3.zero; | ||
| 45 | + mpn.transform.localScale = Vector3.one; | ||
| 46 | + } | ||
| 47 | + // Do things | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + [ClientRpc] | ||
| 51 | + private void RpcGetFiles(string json) | ||
| 52 | + { | ||
| 53 | + var tempList = (IList)MiniJSON.Json.Deserialize(json); | ||
| 54 | + | ||
| 55 | + _files = new List<Dictionary<string, string>>(); | ||
| 56 | + | ||
| 57 | + foreach (IDictionary dict in tempList) | ||
| 58 | + { | ||
| 59 | + var thisDict = new Dictionary<string, string>(); | ||
| 60 | + foreach(DictionaryEntry de in dict) | ||
| 61 | + thisDict.Add(de.Key.ToString(), de.Value.ToString()); | ||
| 62 | + | ||
| 63 | + _files.Add(thisDict); | ||
| 64 | + } | ||
| 9 | } | 65 | } |
| 10 | 66 | ||
| 11 | void Update () | 67 | void Update () |
| 12 | { | 68 | { |
| 13 | - if (Input.GetKeyDown(KeyCode.Q)) | 69 | + if (Input.GetKeyDown(KeyCode.Alpha1)) |
| 14 | - CmdLoadVideo("sample-1920x1024-divx.avi"); | 70 | + { |
| 71 | + var thisDict = _files[0]; | ||
| 72 | + CmdLoadVideo(thisDict["filename"]); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + if (Input.GetKeyDown(KeyCode.Alpha2)) | ||
| 76 | + { | ||
| 77 | + var thisDict = _files[1]; | ||
| 78 | + CmdLoadVideo(thisDict["filename"]); | ||
| 79 | + } | ||
| 15 | } | 80 | } |
| 16 | 81 | ||
| 17 | [Command] | 82 | [Command] |
| 18 | - private void CmdLoadVideo(string file) | 83 | + public void CmdLoadVideo(string file) |
| 19 | { | 84 | { |
| 20 | - MovieLoader.Instance.LoadMovie(file); | 85 | + AppManager.Instance.LoadMovie(file); |
| 21 | } | 86 | } |
| 22 | } | 87 | } | ... | ... |
Assets/_Nest/Scripts/Utility.meta
0 → 100644
Assets/_Nest/Scripts/Utility/MiniJSON.cs
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright (c) 2012 Calvin Rien | ||
| 3 | + * | ||
| 4 | + * Based on the JSON parser by Patrick van Bergen | ||
| 5 | + * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html | ||
| 6 | + * | ||
| 7 | + * Simplified it so that it doesn't throw exceptions | ||
| 8 | + * and can be used in Unity iPhone with maximum code stripping. | ||
| 9 | + * | ||
| 10 | + * Permission is hereby granted, free of charge, to any person obtaining | ||
| 11 | + * a copy of this software and associated documentation files (the | ||
| 12 | + * "Software"), to deal in the Software without restriction, including | ||
| 13 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
| 14 | + * distribute, sublicense, and/or sell copies of the Software, and to | ||
| 15 | + * permit persons to whom the Software is furnished to do so, subject to | ||
| 16 | + * the following conditions: | ||
| 17 | + * | ||
| 18 | + * The above copyright notice and this permission notice shall be | ||
| 19 | + * included in all copies or substantial portions of the Software. | ||
| 20 | + * | ||
| 21 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 22 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 23 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 24 | + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
| 25 | + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
| 26 | + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
| 27 | + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 28 | + */ | ||
| 29 | +using System; | ||
| 30 | +using System.Collections; | ||
| 31 | +using System.Collections.Generic; | ||
| 32 | +using System.IO; | ||
| 33 | +using System.Text; | ||
| 34 | + | ||
| 35 | +namespace MiniJSON { | ||
| 36 | + // Example usage: | ||
| 37 | + // | ||
| 38 | + // using UnityEngine; | ||
| 39 | + // using System.Collections; | ||
| 40 | + // using System.Collections.Generic; | ||
| 41 | + // using MiniJSON; | ||
| 42 | + // | ||
| 43 | + // public class MiniJSONTest : MonoBehaviour { | ||
| 44 | + // void Start () { | ||
| 45 | + // var jsonString = "{ \"array\": [1.44,2,3], " + | ||
| 46 | + // "\"object\": {\"key1\":\"value1\", \"key2\":256}, " + | ||
| 47 | + // "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " + | ||
| 48 | + // "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " + | ||
| 49 | + // "\"int\": 65536, " + | ||
| 50 | + // "\"float\": 3.1415926, " + | ||
| 51 | + // "\"bool\": true, " + | ||
| 52 | + // "\"null\": null }"; | ||
| 53 | + // | ||
| 54 | + // var dict = Json.Deserialize(jsonString) as Dictionary<string,object>; | ||
| 55 | + // | ||
| 56 | + // Debug.Log("deserialized: " + dict.GetType()); | ||
| 57 | + // Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]); | ||
| 58 | + // Debug.Log("dict['string']: " + (string) dict["string"]); | ||
| 59 | + // Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles | ||
| 60 | + // Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs | ||
| 61 | + // Debug.Log("dict['unicode']: " + (string) dict["unicode"]); | ||
| 62 | + // | ||
| 63 | + // var str = Json.Serialize(dict); | ||
| 64 | + // | ||
| 65 | + // Debug.Log("serialized: " + str); | ||
| 66 | + // } | ||
| 67 | + // } | ||
| 68 | + | ||
| 69 | + /// <summary> | ||
| 70 | + /// This class encodes and decodes JSON strings. | ||
| 71 | + /// Spec. details, see http://www.json.org/ | ||
| 72 | + /// | ||
| 73 | + /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary. | ||
| 74 | + /// All numbers are parsed to doubles. | ||
| 75 | + /// </summary> | ||
| 76 | + public static class Json { | ||
| 77 | + /// <summary> | ||
| 78 | + /// Parses the string json into a value | ||
| 79 | + /// </summary> | ||
| 80 | + /// <param name="json">A JSON string.</param> | ||
| 81 | + /// <returns>An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false</returns> | ||
| 82 | + public static object Deserialize(string json) { | ||
| 83 | + // save the string for debug information | ||
| 84 | + if (json == null) { | ||
| 85 | + return null; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + return Parser.Parse(json); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + sealed class Parser : IDisposable { | ||
| 92 | + const string WHITE_SPACE = " \t\n\r"; | ||
| 93 | + const string WORD_BREAK = " \t\n\r{}[],:\""; | ||
| 94 | + | ||
| 95 | + enum TOKEN { | ||
| 96 | + NONE, | ||
| 97 | + CURLY_OPEN, | ||
| 98 | + CURLY_CLOSE, | ||
| 99 | + SQUARED_OPEN, | ||
| 100 | + SQUARED_CLOSE, | ||
| 101 | + COLON, | ||
| 102 | + COMMA, | ||
| 103 | + STRING, | ||
| 104 | + NUMBER, | ||
| 105 | + TRUE, | ||
| 106 | + FALSE, | ||
| 107 | + NULL | ||
| 108 | + }; | ||
| 109 | + | ||
| 110 | + StringReader json; | ||
| 111 | + | ||
| 112 | + Parser(string jsonString) { | ||
| 113 | + json = new StringReader(jsonString); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + public static object Parse(string jsonString) { | ||
| 117 | + using (var instance = new Parser(jsonString)) { | ||
| 118 | + return instance.ParseValue(); | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + public void Dispose() { | ||
| 123 | + json.Dispose(); | ||
| 124 | + json = null; | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + Dictionary<string, object> ParseObject() { | ||
| 128 | + Dictionary<string, object> table = new Dictionary<string, object>(); | ||
| 129 | + | ||
| 130 | + // ditch opening brace | ||
| 131 | + json.Read(); | ||
| 132 | + | ||
| 133 | + // { | ||
| 134 | + while (true) { | ||
| 135 | + switch (NextToken) { | ||
| 136 | + case TOKEN.NONE: | ||
| 137 | + return null; | ||
| 138 | + case TOKEN.COMMA: | ||
| 139 | + continue; | ||
| 140 | + case TOKEN.CURLY_CLOSE: | ||
| 141 | + return table; | ||
| 142 | + default: | ||
| 143 | + // name | ||
| 144 | + string name = ParseString(); | ||
| 145 | + if (name == null) { | ||
| 146 | + return null; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + // : | ||
| 150 | + if (NextToken != TOKEN.COLON) { | ||
| 151 | + return null; | ||
| 152 | + } | ||
| 153 | + // ditch the colon | ||
| 154 | + json.Read(); | ||
| 155 | + | ||
| 156 | + // value | ||
| 157 | + table[name] = ParseValue(); | ||
| 158 | + break; | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + List<object> ParseArray() { | ||
| 164 | + List<object> array = new List<object>(); | ||
| 165 | + | ||
| 166 | + // ditch opening bracket | ||
| 167 | + json.Read(); | ||
| 168 | + | ||
| 169 | + // [ | ||
| 170 | + var parsing = true; | ||
| 171 | + while (parsing) { | ||
| 172 | + TOKEN nextToken = NextToken; | ||
| 173 | + | ||
| 174 | + switch (nextToken) { | ||
| 175 | + case TOKEN.NONE: | ||
| 176 | + return null; | ||
| 177 | + case TOKEN.COMMA: | ||
| 178 | + continue; | ||
| 179 | + case TOKEN.SQUARED_CLOSE: | ||
| 180 | + parsing = false; | ||
| 181 | + break; | ||
| 182 | + default: | ||
| 183 | + object value = ParseByToken(nextToken); | ||
| 184 | + | ||
| 185 | + array.Add(value); | ||
| 186 | + break; | ||
| 187 | + } | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + return array; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + object ParseValue() { | ||
| 194 | + TOKEN nextToken = NextToken; | ||
| 195 | + return ParseByToken(nextToken); | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + object ParseByToken(TOKEN token) { | ||
| 199 | + switch (token) { | ||
| 200 | + case TOKEN.STRING: | ||
| 201 | + return ParseString(); | ||
| 202 | + case TOKEN.NUMBER: | ||
| 203 | + return ParseNumber(); | ||
| 204 | + case TOKEN.CURLY_OPEN: | ||
| 205 | + return ParseObject(); | ||
| 206 | + case TOKEN.SQUARED_OPEN: | ||
| 207 | + return ParseArray(); | ||
| 208 | + case TOKEN.TRUE: | ||
| 209 | + return true; | ||
| 210 | + case TOKEN.FALSE: | ||
| 211 | + return false; | ||
| 212 | + case TOKEN.NULL: | ||
| 213 | + return null; | ||
| 214 | + default: | ||
| 215 | + return null; | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + string ParseString() { | ||
| 220 | + StringBuilder s = new StringBuilder(); | ||
| 221 | + char c; | ||
| 222 | + | ||
| 223 | + // ditch opening quote | ||
| 224 | + json.Read(); | ||
| 225 | + | ||
| 226 | + bool parsing = true; | ||
| 227 | + while (parsing) { | ||
| 228 | + | ||
| 229 | + if (json.Peek() == -1) { | ||
| 230 | + parsing = false; | ||
| 231 | + break; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + c = NextChar; | ||
| 235 | + switch (c) { | ||
| 236 | + case '"': | ||
| 237 | + parsing = false; | ||
| 238 | + break; | ||
| 239 | + case '\\': | ||
| 240 | + if (json.Peek() == -1) { | ||
| 241 | + parsing = false; | ||
| 242 | + break; | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + c = NextChar; | ||
| 246 | + switch (c) { | ||
| 247 | + case '"': | ||
| 248 | + case '\\': | ||
| 249 | + case '/': | ||
| 250 | + s.Append(c); | ||
| 251 | + break; | ||
| 252 | + case 'b': | ||
| 253 | + s.Append('\b'); | ||
| 254 | + break; | ||
| 255 | + case 'f': | ||
| 256 | + s.Append('\f'); | ||
| 257 | + break; | ||
| 258 | + case 'n': | ||
| 259 | + s.Append('\n'); | ||
| 260 | + break; | ||
| 261 | + case 'r': | ||
| 262 | + s.Append('\r'); | ||
| 263 | + break; | ||
| 264 | + case 't': | ||
| 265 | + s.Append('\t'); | ||
| 266 | + break; | ||
| 267 | + case 'u': | ||
| 268 | + var hex = new StringBuilder(); | ||
| 269 | + | ||
| 270 | + for (int i=0; i< 4; i++) { | ||
| 271 | + hex.Append(NextChar); | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + s.Append((char) Convert.ToInt32(hex.ToString(), 16)); | ||
| 275 | + break; | ||
| 276 | + } | ||
| 277 | + break; | ||
| 278 | + default: | ||
| 279 | + s.Append(c); | ||
| 280 | + break; | ||
| 281 | + } | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + return s.ToString(); | ||
| 285 | + } | ||
| 286 | + | ||
| 287 | + object ParseNumber() { | ||
| 288 | + string number = NextWord; | ||
| 289 | + | ||
| 290 | + if (number.IndexOf('.') == -1) { | ||
| 291 | + long parsedInt; | ||
| 292 | + Int64.TryParse(number, out parsedInt); | ||
| 293 | + return parsedInt; | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + double parsedDouble; | ||
| 297 | + Double.TryParse(number, out parsedDouble); | ||
| 298 | + return parsedDouble; | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + void EatWhitespace() { | ||
| 302 | + while (WHITE_SPACE.IndexOf(PeekChar) != -1) { | ||
| 303 | + json.Read(); | ||
| 304 | + | ||
| 305 | + if (json.Peek() == -1) { | ||
| 306 | + break; | ||
| 307 | + } | ||
| 308 | + } | ||
| 309 | + } | ||
| 310 | + | ||
| 311 | + char PeekChar { | ||
| 312 | + get { | ||
| 313 | + return Convert.ToChar(json.Peek()); | ||
| 314 | + } | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + char NextChar { | ||
| 318 | + get { | ||
| 319 | + return Convert.ToChar(json.Read()); | ||
| 320 | + } | ||
| 321 | + } | ||
| 322 | + | ||
| 323 | + string NextWord { | ||
| 324 | + get { | ||
| 325 | + StringBuilder word = new StringBuilder(); | ||
| 326 | + | ||
| 327 | + while (WORD_BREAK.IndexOf(PeekChar) == -1) { | ||
| 328 | + word.Append(NextChar); | ||
| 329 | + | ||
| 330 | + if (json.Peek() == -1) { | ||
| 331 | + break; | ||
| 332 | + } | ||
| 333 | + } | ||
| 334 | + | ||
| 335 | + return word.ToString(); | ||
| 336 | + } | ||
| 337 | + } | ||
| 338 | + | ||
| 339 | + TOKEN NextToken { | ||
| 340 | + get { | ||
| 341 | + EatWhitespace(); | ||
| 342 | + | ||
| 343 | + if (json.Peek() == -1) { | ||
| 344 | + return TOKEN.NONE; | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + char c = PeekChar; | ||
| 348 | + switch (c) { | ||
| 349 | + case '{': | ||
| 350 | + return TOKEN.CURLY_OPEN; | ||
| 351 | + case '}': | ||
| 352 | + json.Read(); | ||
| 353 | + return TOKEN.CURLY_CLOSE; | ||
| 354 | + case '[': | ||
| 355 | + return TOKEN.SQUARED_OPEN; | ||
| 356 | + case ']': | ||
| 357 | + json.Read(); | ||
| 358 | + return TOKEN.SQUARED_CLOSE; | ||
| 359 | + case ',': | ||
| 360 | + json.Read(); | ||
| 361 | + return TOKEN.COMMA; | ||
| 362 | + case '"': | ||
| 363 | + return TOKEN.STRING; | ||
| 364 | + case ':': | ||
| 365 | + return TOKEN.COLON; | ||
| 366 | + case '0': | ||
| 367 | + case '1': | ||
| 368 | + case '2': | ||
| 369 | + case '3': | ||
| 370 | + case '4': | ||
| 371 | + case '5': | ||
| 372 | + case '6': | ||
| 373 | + case '7': | ||
| 374 | + case '8': | ||
| 375 | + case '9': | ||
| 376 | + case '-': | ||
| 377 | + return TOKEN.NUMBER; | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + string word = NextWord; | ||
| 381 | + | ||
| 382 | + switch (word) { | ||
| 383 | + case "false": | ||
| 384 | + return TOKEN.FALSE; | ||
| 385 | + case "true": | ||
| 386 | + return TOKEN.TRUE; | ||
| 387 | + case "null": | ||
| 388 | + return TOKEN.NULL; | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + return TOKEN.NONE; | ||
| 392 | + } | ||
| 393 | + } | ||
| 394 | + } | ||
| 395 | + | ||
| 396 | + /// <summary> | ||
| 397 | + /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string | ||
| 398 | + /// </summary> | ||
| 399 | + /// <param name="json">A Dictionary<string, object> / List<object></param> | ||
| 400 | + /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns> | ||
| 401 | + public static string Serialize(object obj) { | ||
| 402 | + return Serializer.Serialize(obj); | ||
| 403 | + } | ||
| 404 | + | ||
| 405 | + sealed class Serializer { | ||
| 406 | + StringBuilder builder; | ||
| 407 | + | ||
| 408 | + Serializer() { | ||
| 409 | + builder = new StringBuilder(); | ||
| 410 | + } | ||
| 411 | + | ||
| 412 | + public static string Serialize(object obj) { | ||
| 413 | + var instance = new Serializer(); | ||
| 414 | + | ||
| 415 | + instance.SerializeValue(obj); | ||
| 416 | + | ||
| 417 | + return instance.builder.ToString(); | ||
| 418 | + } | ||
| 419 | + | ||
| 420 | + void SerializeValue(object value) { | ||
| 421 | + IList asList; | ||
| 422 | + IDictionary asDict; | ||
| 423 | + string asStr; | ||
| 424 | + | ||
| 425 | + if (value == null) { | ||
| 426 | + builder.Append("null"); | ||
| 427 | + } | ||
| 428 | + else if ((asStr = value as string) != null) { | ||
| 429 | + SerializeString(asStr); | ||
| 430 | + } | ||
| 431 | + else if (value is bool) { | ||
| 432 | + builder.Append(value.ToString().ToLower()); | ||
| 433 | + } | ||
| 434 | + else if ((asList = value as IList) != null) { | ||
| 435 | + SerializeArray(asList); | ||
| 436 | + } | ||
| 437 | + else if ((asDict = value as IDictionary) != null) { | ||
| 438 | + SerializeObject(asDict); | ||
| 439 | + } | ||
| 440 | + else if (value is char) { | ||
| 441 | + SerializeString(value.ToString()); | ||
| 442 | + } | ||
| 443 | + else { | ||
| 444 | + SerializeOther(value); | ||
| 445 | + } | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + void SerializeObject(IDictionary obj) { | ||
| 449 | + bool first = true; | ||
| 450 | + | ||
| 451 | + builder.Append('{'); | ||
| 452 | + | ||
| 453 | + foreach (object e in obj.Keys) { | ||
| 454 | + if (!first) { | ||
| 455 | + builder.Append(','); | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + SerializeString(e.ToString()); | ||
| 459 | + builder.Append(':'); | ||
| 460 | + | ||
| 461 | + SerializeValue(obj[e]); | ||
| 462 | + | ||
| 463 | + first = false; | ||
| 464 | + } | ||
| 465 | + | ||
| 466 | + builder.Append('}'); | ||
| 467 | + } | ||
| 468 | + | ||
| 469 | + void SerializeArray(IList anArray) { | ||
| 470 | + builder.Append('['); | ||
| 471 | + | ||
| 472 | + bool first = true; | ||
| 473 | + | ||
| 474 | + foreach (object obj in anArray) { | ||
| 475 | + if (!first) { | ||
| 476 | + builder.Append(','); | ||
| 477 | + } | ||
| 478 | + | ||
| 479 | + SerializeValue(obj); | ||
| 480 | + | ||
| 481 | + first = false; | ||
| 482 | + } | ||
| 483 | + | ||
| 484 | + builder.Append(']'); | ||
| 485 | + } | ||
| 486 | + | ||
| 487 | + void SerializeString(string str) { | ||
| 488 | + builder.Append('\"'); | ||
| 489 | + | ||
| 490 | + char[] charArray = str.ToCharArray(); | ||
| 491 | + foreach (var c in charArray) { | ||
| 492 | + switch (c) { | ||
| 493 | + case '"': | ||
| 494 | + builder.Append("\\\""); | ||
| 495 | + break; | ||
| 496 | + case '\\': | ||
| 497 | + builder.Append("\\\\"); | ||
| 498 | + break; | ||
| 499 | + case '\b': | ||
| 500 | + builder.Append("\\b"); | ||
| 501 | + break; | ||
| 502 | + case '\f': | ||
| 503 | + builder.Append("\\f"); | ||
| 504 | + break; | ||
| 505 | + case '\n': | ||
| 506 | + builder.Append("\\n"); | ||
| 507 | + break; | ||
| 508 | + case '\r': | ||
| 509 | + builder.Append("\\r"); | ||
| 510 | + break; | ||
| 511 | + case '\t': | ||
| 512 | + builder.Append("\\t"); | ||
| 513 | + break; | ||
| 514 | + default: | ||
| 515 | + int codepoint = Convert.ToInt32(c); | ||
| 516 | + if ((codepoint >= 32) && (codepoint <= 126)) { | ||
| 517 | + builder.Append(c); | ||
| 518 | + } | ||
| 519 | + else { | ||
| 520 | + builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0')); | ||
| 521 | + } | ||
| 522 | + break; | ||
| 523 | + } | ||
| 524 | + } | ||
| 525 | + | ||
| 526 | + builder.Append('\"'); | ||
| 527 | + } | ||
| 528 | + | ||
| 529 | + void SerializeOther(object value) { | ||
| 530 | + if (value is float | ||
| 531 | + || value is int | ||
| 532 | + || value is uint | ||
| 533 | + || value is long | ||
| 534 | + || value is double | ||
| 535 | + || value is sbyte | ||
| 536 | + || value is byte | ||
| 537 | + || value is short | ||
| 538 | + || value is ushort | ||
| 539 | + || value is ulong | ||
| 540 | + || value is decimal) { | ||
| 541 | + builder.Append(value.ToString()); | ||
| 542 | + } | ||
| 543 | + else { | ||
| 544 | + SerializeString(value.ToString()); | ||
| 545 | + } | ||
| 546 | + } | ||
| 547 | + } | ||
| 548 | + } | ||
| 549 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
No preview for this file type
No preview for this file type
-
Please register or sign in to post a comment