diff options
author | Sean Dague | 2008-09-12 15:04:13 +0000 |
---|---|---|
committer | Sean Dague | 2008-09-12 15:04:13 +0000 |
commit | 1b333a0f58d345d37222eb1af821e6ebd457378c (patch) | |
tree | a3f6af065f3b92a2282d7ddb320349237c7dec2a /OpenSim/Region/ScriptEngine/Common | |
parent | Mantis#2165. Thank you kindly, CMickeyB for a patch that: (diff) | |
download | opensim-SC_OLD-1b333a0f58d345d37222eb1af821e6ebd457378c.zip opensim-SC_OLD-1b333a0f58d345d37222eb1af821e6ebd457378c.tar.gz opensim-SC_OLD-1b333a0f58d345d37222eb1af821e6ebd457378c.tar.bz2 opensim-SC_OLD-1b333a0f58d345d37222eb1af821e6ebd457378c.tar.xz |
From: Rob Smart <SMARTROB@uk.ibm.com>
Implement an osParseJSON method useful for handling simple JSON returns
from http requests. This will only work in C# at this point.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common')
3 files changed, 197 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs index 4fba1fd..1b7cc48 100644 --- a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs +++ b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs | |||
@@ -2035,6 +2035,11 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
2035 | } | 2035 | } |
2036 | 2036 | ||
2037 | 2037 | ||
2038 | public System.Collections.Hashtable osParseJSON(string JSON) | ||
2039 | { | ||
2040 | return m_LSL_Functions.osParseJSON(JSON); | ||
2041 | } | ||
2042 | |||
2038 | //for testing purposes only | 2043 | //for testing purposes only |
2039 | public void osSetParcelMediaTime(double time) | 2044 | public void osSetParcelMediaTime(double time) |
2040 | { | 2045 | { |
diff --git a/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs index 8b5e879..6c7b9da 100644 --- a/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs | |||
@@ -25,6 +25,7 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections; | ||
28 | using OpenMetaverse; | 29 | using OpenMetaverse; |
29 | using Nini.Config; | 30 | using Nini.Config; |
30 | using OpenSim.Framework.Console; | 31 | using OpenSim.Framework.Console; |
@@ -582,5 +583,194 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
582 | { | 583 | { |
583 | World.ParcelMediaSetTime((float)time); | 584 | World.ParcelMediaSetTime((float)time); |
584 | } | 585 | } |
586 | |||
587 | public Hashtable osParseJSON(string JSON) | ||
588 | { | ||
589 | // see http://www.json.org/ for more details on JSON | ||
590 | |||
591 | string currentKey=null; | ||
592 | Stack objectStack = new Stack(); // objects in JSON can be nested so we need to keep a track of this | ||
593 | Hashtable jsondata = new Hashtable(); // the hashtable to be returned | ||
594 | |||
595 | try | ||
596 | { | ||
597 | |||
598 | // iterate through the serialised stream of tokens and store at the right depth in the hashtable | ||
599 | // the top level hashtable may contain more nested hashtables within it each containing an objects representation | ||
600 | for (int i=0;i<JSON.Length; i++) | ||
601 | { | ||
602 | |||
603 | // Console.WriteLine(""+JSON[i]); | ||
604 | switch(JSON[i]) | ||
605 | { | ||
606 | case '{': | ||
607 | // create hashtable and add it to the stack or array if we are populating one, we can have a lot of nested objects in JSON | ||
608 | |||
609 | Hashtable currentObject = new Hashtable(); | ||
610 | if(objectStack.Count==0) // the stack should only be empty for the first outer object | ||
611 | { | ||
612 | |||
613 | objectStack.Push(jsondata); | ||
614 | } | ||
615 | else if(objectStack.Peek().ToString()=="System.Collections.ArrayList") | ||
616 | { | ||
617 | // add it to the parent array | ||
618 | ((ArrayList)objectStack.Peek()).Add(currentObject); | ||
619 | objectStack.Push(currentObject); | ||
620 | } | ||
621 | else | ||
622 | { | ||
623 | // add it to the parent hashtable | ||
624 | ((Hashtable)objectStack.Peek()).Add(currentKey,currentObject); | ||
625 | objectStack.Push(currentObject); | ||
626 | } | ||
627 | |||
628 | // clear the key | ||
629 | currentKey=null; | ||
630 | break; | ||
631 | case '}': | ||
632 | // pop the hashtable off the stack | ||
633 | objectStack.Pop(); | ||
634 | break; | ||
635 | case '"':// string boundary | ||
636 | |||
637 | string tokenValue=""; | ||
638 | i++; // move to next char | ||
639 | |||
640 | // just loop through until the next quote mark storing the string | ||
641 | while(JSON[i]!='"') | ||
642 | { | ||
643 | tokenValue+=JSON[i++]; | ||
644 | } | ||
645 | |||
646 | // ok we've got a string, if we've got an array on the top of the stack then we store it | ||
647 | if(objectStack.Peek().ToString()=="System.Collections.ArrayList") | ||
648 | { | ||
649 | ((ArrayList)objectStack.Peek()).Add(tokenValue); | ||
650 | } | ||
651 | else if(currentKey==null) // no key stored and its not an array this must be a key so store it | ||
652 | { | ||
653 | currentKey = tokenValue; | ||
654 | } | ||
655 | else | ||
656 | { | ||
657 | // we have a key so lets store this value | ||
658 | ((Hashtable)objectStack.Peek()).Add(currentKey,tokenValue); | ||
659 | // now lets clear the key, we're done with it and moving on | ||
660 | currentKey=null; | ||
661 | } | ||
662 | |||
663 | break; | ||
664 | case ':':// key : value separator | ||
665 | // just ignore | ||
666 | break; | ||
667 | case ' ':// spaces | ||
668 | // just ignore | ||
669 | break; | ||
670 | case '[': // array start | ||
671 | ArrayList currentArray = new ArrayList(); | ||
672 | |||
673 | if(objectStack.Peek().ToString()=="System.Collections.ArrayList") | ||
674 | { | ||
675 | ((ArrayList)objectStack.Peek()).Add(currentArray); | ||
676 | } | ||
677 | else | ||
678 | { | ||
679 | ((Hashtable)objectStack.Peek()).Add(currentKey,currentArray); | ||
680 | // clear the key | ||
681 | currentKey=null; | ||
682 | } | ||
683 | objectStack.Push(currentArray); | ||
684 | |||
685 | break; | ||
686 | case ',':// seperator | ||
687 | // just ignore | ||
688 | break; | ||
689 | case ']'://Array end | ||
690 | // pop the array off the stack | ||
691 | objectStack.Pop(); | ||
692 | break; | ||
693 | case 't': // we've found a character start not in quotes, it must be a boolean true | ||
694 | |||
695 | if(objectStack.Peek().ToString()=="System.Collections.ArrayList") | ||
696 | { | ||
697 | ((ArrayList)objectStack.Peek()).Add(true); | ||
698 | } | ||
699 | else | ||
700 | { | ||
701 | ((Hashtable)objectStack.Peek()).Add(currentKey,true); | ||
702 | } | ||
703 | |||
704 | //advance the counter to the letter 'e' | ||
705 | i = i+3; | ||
706 | break; | ||
707 | case 'f': // we've found a character start not in quotes, it must be a boolean false | ||
708 | |||
709 | if(objectStack.Peek().ToString()=="System.Collections.ArrayList") | ||
710 | { | ||
711 | ((ArrayList)objectStack.Peek()).Add(false); | ||
712 | } | ||
713 | else | ||
714 | { | ||
715 | ((Hashtable)objectStack.Peek()).Add(currentKey,false); | ||
716 | } | ||
717 | //advance the counter to the letter 'e' | ||
718 | i = i+4; | ||
719 | break; | ||
720 | default: | ||
721 | // ok here we're catching all numeric types int,double,long we might want to spit these up mr accurately | ||
722 | // but for now we'll just do them as strings | ||
723 | |||
724 | string numberValue=""; | ||
725 | |||
726 | // just loop through until the next known marker quote mark storing the string | ||
727 | while(JSON[i]!='"' && JSON[i]!=',' && JSON[i]!=']' && JSON[i]!='}' && JSON[i]!=' ') | ||
728 | { | ||
729 | numberValue+=""+JSON[i++]; | ||
730 | } | ||
731 | |||
732 | i--; // we want to process this caracter that marked the end of this string in the main loop | ||
733 | |||
734 | // ok we've got a string, if we've got an array on the top of the stack then we store it | ||
735 | if(objectStack.Peek().ToString()=="System.Collections.ArrayList") | ||
736 | { | ||
737 | ((ArrayList)objectStack.Peek()).Add(numberValue); | ||
738 | } | ||
739 | else | ||
740 | { | ||
741 | // we have a key so lets store this value | ||
742 | ((Hashtable)objectStack.Peek()).Add(currentKey,numberValue); | ||
743 | // now lets clear the key, we're done with it and moving on | ||
744 | currentKey=null; | ||
745 | } | ||
746 | |||
747 | |||
748 | break; | ||
749 | } | ||
750 | |||
751 | |||
752 | |||
753 | |||
754 | } | ||
755 | |||
756 | } | ||
757 | catch(Exception e) | ||
758 | { | ||
759 | LSLError("osParseJSON: The JSON string is not valid " + JSON); | ||
760 | } | ||
761 | |||
762 | return jsondata; | ||
763 | |||
764 | |||
765 | } | ||
766 | |||
767 | |||
768 | |||
769 | |||
770 | |||
771 | |||
772 | |||
773 | |||
774 | |||
585 | } | 775 | } |
586 | } | 776 | } |
diff --git a/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands_Interface.cs b/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands_Interface.cs index bbc6d2d..7daef7d 100644 --- a/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands_Interface.cs +++ b/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands_Interface.cs | |||
@@ -63,6 +63,8 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
63 | void osSetStateEvents(int events); | 63 | void osSetStateEvents(int events); |
64 | 64 | ||
65 | void osOpenRemoteDataChannel(string channel); | 65 | void osOpenRemoteDataChannel(string channel); |
66 | |||
67 | System.Collections.Hashtable osParseJSON(string JSON); | ||
66 | 68 | ||
67 | string osGetScriptEngineName(); | 69 | string osGetScriptEngineName(); |
68 | void osSetParcelMediaTime(double time); | 70 | void osSetParcelMediaTime(double time); |