/*************************************************************************************** Copyright 2012 Greg Dennis Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. File Name: JsonArray.cs Namespace: Manatee.Json Class Name: JsonArray Purpose: Represents a collection of JSON values.***************************************************************************************/usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingManatee.Json.Enumerations;usingManatee.Json.Exceptions;usingManatee.Json.Helpers;usingManatee.StateMachine;usingManatee.StateMachine.Exceptions;namespaceManatee.Json{/// <summary>/// Represents a collection of JSON values./// </summary>/// <remarks>/// A value can consist of a string, a numeric value, a boolean (true or false), a null placeholder,/// a JSON array of values, or a nested JSON object./// </remarks>publicclassJsonArray:List<JsonValue>{enumState{Start,Value,End}privatestaticreadonlyStateMachine<State,JsonInput>StateMachine=newStateMachine<State,JsonInput>();privatereadonlystring_source;privateint_index;privateJsonValue_value;privatebool_done;readonlyInputStream<JsonInput>_stream=newInputStream<JsonInput>();staticJsonArray(){StateMachine[State.Start,JsonInput.OpenBracket]=GotStart;StateMachine[State.Value,JsonInput.OpenBrace]=GotValue;StateMachine[State.Value,JsonInput.Quote]=GotValue;StateMachine[State.Value,JsonInput.Number]=GotValue;StateMachine[State.Value,JsonInput.Boolean]=GotValue;StateMachine[State.Value,JsonInput.Null]=GotValue;StateMachine[State.Value,JsonInput.OpenBracket]=GotValue;StateMachine[State.Value,JsonInput.CloseBracket]=GotEmpty;StateMachine[State.End,JsonInput.Comma]=GotEnd;StateMachine[State.End,JsonInput.CloseBracket]=GotEnd;StateMachine.UpdateFunction=GetNextInput;}/// <summary>/// Creates an empty instance of a JSON object./// </summary>publicJsonArray(){}/// <summary>/// Creates an instance of a JSON array and fills it by parsing the/// supplied string starting at the indicated index./// </summary>/// <param name="s">A string.</param>/// <param name="i">The index at which the array starts.</param>internalJsonArray(strings,refinti):this(){_source=s;i=Parse(i);}/// <summary>/// Finalizes memory management responsibilities./// </summary>~JsonArray(){StateMachine.UnregisterOwner(this);}/// <summary>/// Creates a string representation of the JSON data./// </summary>/// <param name="indentLevel">The indention level for the array.</param>/// <returns>A string.</returns>publicstringGetIndentedString(intindentLevel=0){if(Count==0)returnJsonValue.Null.ToString();stringtab0=string.Empty.PadLeft(indentLevel,'\t'),tab1=string.Empty.PadLeft(indentLevel+1,'\t'),s="[\n";inti;for(i=0;i<Count-1;i++){if(this[i]==null)this[i]=newJsonValue();s+=string.Format("{0}{1},\n",tab1,this[i].GetIndentedString(indentLevel+1));}s+=string.Format("{0}{1}\n{2}]",tab1,this[i].GetIndentedString(indentLevel+1),tab0);returns;}privateintParse(inti){_stream.Clear();_value=null;_index=i;_done=false;try{StateMachine.Run(this,State.Start,_stream);if(!_done)thrownewJsonSyntaxException(_index);}catch(InputNotValidForStateException<State,JsonInput>){thrownewJsonSyntaxException(_index);}catch(StateNotValidException<State>){thrownewJsonSyntaxException(_index);}catch(ActionNotDefinedForStateAndInputException<State,JsonInput>){thrownewJsonSyntaxException(_index);}catch(Exceptione){e.Data.Add("source",_source);e.Data.Add("index",_index);throw;}return_index;}/// <summary>/// Creates a string representation of the JSON data./// </summary>/// <returns>A string.</returns>/// <remarks>/// Passing the returned string back into the parser will result in a copy of/// this Json array./// </remarks>publicoverridestringToString(){if(Count==0)return"[]";return"["+string.Join(",",fromvalueinthisselectvalue.ToString())+"]";}/// <summary>/// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>./// </summary>/// <returns>/// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false./// </returns>/// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>. </param><filterpriority>2</filterpriority>publicoverrideboolEquals(objectobj){varjson=objasJsonArray;if(json==null)returnfalse;returnthis.All(json.Contains)&&(Count==json.Count);}/// <summary>/// Serves as a hash function for a particular type. /// </summary>/// <returns>/// A hash code for the current <see cref="T:System.Object"/>./// </returns>/// <filterpriority>2</filterpriority>publicoverrideintGetHashCode(){returnbase.GetHashCode();}privatestaticvoidGetNextInput(objectowner){vararray=ownerasJsonArray;if(array==null)return;if(array._done||(array._index==array._source.Length))return;try{varnext=CharacterConverter.Item(array._source[array._index++]);array._stream.Add(next);}catch(KeyNotFoundException){thrownewJsonSyntaxException(array._index);}}privatestaticStateGotStart(objectowner,JsonInputinput){returnState.Value;}privatestaticStateGotValue(objectowner,JsonInputinput){vararray=ownerasJsonArray;array._value=JsonValue.Parse(array._source,refarray._index);returnState.End;}privatestaticStateGotEmpty(objectowner,JsonInputinput){vararray=ownerasJsonArray;array._done=(input==JsonInput.CloseBracket);if(array.Count!=0)thrownewJsonSyntaxException(array._index);returnState.Value;}privatestaticStateGotEnd(objectowner,JsonInputinput){vararray=ownerasJsonArray;array.Add(array._value);array._done=(input==JsonInput.CloseBracket);returnState.Value;}}}