by 널부러 2014. 3. 11. 21:43

http://wiki.unity3d.com/index.php/SimpleJSON 에 공개 되어있는 소스에

long(64bit) 자료형을 읽고 쓸수 있는 기능과 숫자형 자료형 데이터는 큰따옴표가 안붙도록 수정한 버전입니다.


간단한 테스트에서는 문제가 없었지만 만약 문제가 생길때는 책임지지 않습니다.

필요하심 마구 퍼가셔도 됨둥...


아래 코드를 적용한 예제

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SimpleJSON;

namespace TestJSON
{
    class Program
    {
        static void Main(string[] args)
        {
            // 입력 
            var input = new JSONClass();
            input["bool"].AsBool = false;
            input["int"].AsInt = 2147483647;
            input["long"].AsLong = 9223372036854775807;
            input["float"].AsFloat = 3.402823466E+38F;
            input["double"].AsDouble = 3.402823466E+200;
            input["string"] = "test string...";
            input["array"][0].AsInt = 100;
            input["array"][1].AsInt = 200;
            input["array"][2].AsInt = 300;
            input["array2"][0] = "test100";
            input["array2"][1] = "test200";
            input["array2"][2] = "test300";

            Console.WriteLine("input JSON : {0}", input.ToString());

            // 출력
            var output = JSON.Parse(input.ToString());
            bool value1 = output["bool"].AsBool;
            int value2 = output["int"].AsInt;
            long value3 = output["long"].AsLong;
            float value4 = output["float"].AsFloat;
            double value5 = output["double"].AsDouble;
            String value6 = output["string"];
            var value7 = output["array"].AsArray;
            var value8 = output["array2"].AsArray;

            Console.WriteLine("output JSON : {0}", output.ToString());
        }
    }
}
수정된 SimpleJSON 코드
//#define USE_SharpZipLib
#if !UNITY_WEBPLAYER
#define USE_FileIO
#endif

/* * * * *
 * A simple JSON Parser / builder
 * ------------------------------
 * 
 * It mainly has been written as a simple JSON parser. It can build a JSON string
 * from the node-tree, or generate a node tree from any valid JSON string.
 * 
 * If you want to use compression when saving to file / stream / B64 you have to include
 * SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ ) in your project and
 * define "USE_SharpZipLib" at the top of the file
 * 
 * Written by Bunny83 
 * 2012-06-09
 * 
 * Features / attributes:
 * - provides strongly typed node classes and lists / dictionaries
 * - provides easy access to class members / array items / data values
 * - the parser ignores data types. Each value is a string.
 * - only double quotes (") are used for quoting strings.
 * - values and names are not restricted to quoted strings. They simply add up and are trimmed.
 * - There are only 3 types: arrays(JSONArray), objects(JSONClass) and values(JSONData)
 * - provides "casting" properties to easily convert to / from those types:
 *   int / float / double / bool
 * - provides a common interface for each node so no explicit casting is required.
 * - the parser try to avoid errors, but if malformed JSON is parsed the result is undefined
 * 
 * 
 * 2012-12-17 Update:
 * - Added internal JSONLazyCreator class which simplifies the construction of a JSON tree
 *   Now you can simple reference any item that doesn't exist yet and it will return a JSONLazyCreator
 *   The class determines the required type by it's further use, creates the type and removes itself.
 * - Added binary serialization / deserialization.
 * - Added support for BZip2 zipped binary format. Requires the SharpZipLib ( http://www.icsharpcode.net/opensource/sharpziplib/ )
 *   The usage of the SharpZipLib library can be disabled by removing or commenting out the USE_SharpZipLib define at the top
 * - The serializer uses different types when it comes to store the values. Since my data values
 *   are all of type string, the serializer will "try" which format fits best. The order is: int, float, double, bool, string.
 *   It's not the most efficient way but for a moderate amount of data it should work on all platforms.
 * 
 * * * * */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;


namespace SimpleJSON
{
    public enum JSONBinaryTag
    {
        None = 0,
        Array = 1,
        Class = 2,
        Value = 3,
        IntValue = 4,
        DoubleValue = 5,
        BoolValue = 6,
        FloatValue = 7,
        LongValue = 8,
    }

    public class JSONNode
    {
        #region common interface
        public virtual void Add(string aKey, JSONNode aItem) { }
        public virtual JSONNode this[int aIndex] { get { return null; } set { } }
        public virtual JSONNode this[string aKey] { get { return null; } set { } }
        public virtual string Value { get { return ""; } set { } }
        public virtual int Count { get { return 0; } }

        public virtual void Add(JSONNode aItem)
        {
            Add("", aItem);
        }

        public virtual JSONNode Remove(string aKey) { return null; }
        public virtual JSONNode Remove(int aIndex) { return null; }
        public virtual JSONNode Remove(JSONNode aNode) { return aNode; }

        public virtual IEnumerable<JSONNode> Childs { get { yield break; } }
        public IEnumerable<JSONNode> DeepChilds
        {
            get
            {
                foreach (var C in Childs)
                    foreach (var D in C.DeepChilds)
                        yield return D;
            }
        }

        public override string ToString()
        {
            return "JSONNode";
        }
        public virtual string ToString(string aPrefix)
        {
            return "JSONNode";
        }

        #endregion common interface

        #region typecasting properties

        // Check data on additional variables in double quotes.
        private bool m_IsDoubleQuotes = false;
        public bool IsDoubleQuotes
        {
            get { return m_IsDoubleQuotes; }
            private set { }
        }

        public virtual int AsInt
        {
            get
            {
                m_IsDoubleQuotes = true;
                int v = 0;
                if (int.TryParse(Value, out v))
                    return v;
                return 0;
            }
            set
            {
                m_IsDoubleQuotes = true;
                Value = value.ToString();
            }
        }
        public virtual long AsLong
        {
            get
            {
                m_IsDoubleQuotes = true;
                long v = 0;
                if (long.TryParse(Value, out v))
                    return v;
                return 0;
            }
            set
            {
                m_IsDoubleQuotes = true;
                Value = value.ToString();
            }
        }
        public virtual float AsFloat
        {
            get
            {
                m_IsDoubleQuotes = true;
                float v = 0.0f;
                if (float.TryParse(Value, out v))
                    return v;
                return 0.0f;
            }
            set
            {
                m_IsDoubleQuotes = true;
                Value = value.ToString();
            }
        }
        public virtual double AsDouble
        {
            get
            {
                m_IsDoubleQuotes = true;
                double v = 0.0;
                if (double.TryParse(Value, out v))
                    return v;
                return 0.0;
            }
            set
            {
                m_IsDoubleQuotes = true;
                Value = value.ToString();
            }
        }
        public virtual bool AsBool
        {
            get
            {
                m_IsDoubleQuotes = true;
                bool v = false;
                if (bool.TryParse(Value, out v))
                    return v;
                return !string.IsNullOrEmpty(Value);
            }
            set
            {
                m_IsDoubleQuotes = true;
                Value = (value) ? "true" : "false";
            }
        }
        public virtual JSONArray AsArray
        {
            get
            {
                return this as JSONArray;
            }
        }
        public virtual JSONClass AsObject
        {
            get
            {
                return this as JSONClass;
            }
        }


        #endregion typecasting properties

        #region operators
        public static implicit operator JSONNode(string s)
        {
            return new JSONData(s);
        }
        public static implicit operator string(JSONNode d)
        {
            return (d == null) ? null : d.Value;
        }
        public static bool operator ==(JSONNode a, object b)
        {
            if (b == null && a is JSONLazyCreator)
                return true;
            return System.Object.ReferenceEquals(a, b);
        }

        public static bool operator !=(JSONNode a, object b)
        {
            return !(a == b);
        }
        public override bool Equals(object obj)
        {
            return System.Object.ReferenceEquals(this, obj);
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }


        #endregion operators

        internal static string Escape(string aText)
        {
            string result = "";
            foreach (char c in aText)
            {
                switch (c)
                {
                    case '\\': result += "\\\\"; break;
                    case '\"': result += "\\\""; break;
                    case '\n': result += "\\n"; break;
                    case '\r': result += "\\r"; break;
                    case '\t': result += "\\t"; break;
                    case '\b': result += "\\b"; break;
                    case '\f': result += "\\f"; break;
                    default: result += c; break;
                }
            }
            return result;
        }

        public static JSONNode Parse(string aJSON)
        {
            Stack<JSONNode> stack = new Stack<JSONNode>();
            JSONNode ctx = null;
            int i = 0;
            string Token = "";
            string TokenName = "";
            bool QuoteMode = false;
            while (i < aJSON.Length)
            {
                switch (aJSON[i])
                {
                    case '{':
                        if (QuoteMode)
                        {
                            Token += aJSON[i];
                            break;
                        }
                        stack.Push(new JSONClass());
                        if (ctx != null)
                        {
                            TokenName = TokenName.Trim();
                            if (ctx is JSONArray)
                                ctx.Add(stack.Peek());
                            else if (TokenName != "")
                                ctx.Add(TokenName, stack.Peek());
                        }
                        TokenName = "";
                        Token = "";
                        ctx = stack.Peek();
                        break;

                    case '[':
                        if (QuoteMode)
                        {
                            Token += aJSON[i];
                            break;
                        }

                        stack.Push(new JSONArray());
                        if (ctx != null)
                        {
                            TokenName = TokenName.Trim();
                            if (ctx is JSONArray)
                                ctx.Add(stack.Peek());
                            else if (TokenName != "")
                                ctx.Add(TokenName, stack.Peek());
                        }
                        TokenName = "";
                        Token = "";
                        ctx = stack.Peek();
                        break;

                    case '}':
                    case ']':
                        if (QuoteMode)
                        {
                            Token += aJSON[i];
                            break;
                        }
                        if (stack.Count == 0)
                            throw new Exception("JSON Parse: Too many closing brackets");

                        stack.Pop();
                        if (Token != "")
                        {
                            TokenName = TokenName.Trim();
                            if (ctx is JSONArray)
                                ctx.Add(Token);
                            else if (TokenName != "")
                                ctx.Add(TokenName, Token);
                        }
                        TokenName = "";
                        Token = "";
                        if (stack.Count > 0)
                            ctx = stack.Peek();
                        break;

                    case ':':
                        if (QuoteMode)
                        {
                            Token += aJSON[i];
                            break;
                        }
                        TokenName = Token;
                        Token = "";
                        break;

                    case '"':
                        QuoteMode ^= true;
                        break;

                    case ',':
                        if (QuoteMode)
                        {
                            Token += aJSON[i];
                            break;
                        }
                        if (Token != "")
                        {
                            if (ctx is JSONArray)
                                ctx.Add(Token);
                            else if (TokenName != "")
                                ctx.Add(TokenName, Token);
                        }
                        TokenName = "";
                        Token = "";
                        break;

                    case '\r':
                    case '\n':
                        break;

                    case ' ':
                    case '\t':
                        if (QuoteMode)
                            Token += aJSON[i];
                        break;

                    case '\\':
                        ++i;
                        if (QuoteMode)
                        {
                            char C = aJSON[i];
                            switch (C)
                            {
                                case 't': Token += '\t'; break;
                                case 'r': Token += '\r'; break;
                                case 'n': Token += '\n'; break;
                                case 'b': Token += '\b'; break;
                                case 'f': Token += '\f'; break;
                                case 'u':
                                    {
                                        string s = aJSON.Substring(i + 1, 4);
                                        Token += (char)int.Parse(s, System.Globalization.NumberStyles.AllowHexSpecifier);
                                        i += 4;
                                        break;
                                    }
                                default: Token += C; break;
                            }
                        }
                        break;

                    default:
                        Token += aJSON[i];
                        break;
                }
                ++i;
            }
            if (QuoteMode)
            {
                throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
            }
            return ctx;
        }

        public virtual void Serialize(System.IO.BinaryWriter aWriter) { }

        public void SaveToStream(System.IO.Stream aData)
        {
            var W = new System.IO.BinaryWriter(aData);
            Serialize(W);
        }

#if USE_SharpZipLib
        public void SaveToCompressedStream(System.IO.Stream aData)
        {
            using (var gzipOut = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(aData))
            {
                gzipOut.IsStreamOwner = false;
                SaveToStream(gzipOut);
                gzipOut.Close();
            }
        }
 
        public void SaveToCompressedFile(string aFileName)
        {
#if USE_FileIO
            System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName);
            using(var F = System.IO.File.OpenWrite(aFileName))
            {
                SaveToCompressedStream(F);
            }
#else
            throw new Exception("Can't use File IO stuff in webplayer");
#endif
        }
        public string SaveToCompressedBase64()
        {
            using (var stream = new System.IO.MemoryStream())
            {
                SaveToCompressedStream(stream);
                stream.Position = 0;
                return System.Convert.ToBase64String(stream.ToArray());
            }
        }
 
#else
        public void SaveToCompressedStream(System.IO.Stream aData)
        {
            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
        }
        public void SaveToCompressedFile(string aFileName)
        {
            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
        }
        public string SaveToCompressedBase64()
        {
            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
        }
#endif

        public void SaveToFile(string aFileName)
        {
#if USE_FileIO
            System.IO.Directory.CreateDirectory((new System.IO.FileInfo(aFileName)).Directory.FullName);
            using (var F = System.IO.File.OpenWrite(aFileName))
            {
                SaveToStream(F);
            }
#else
            throw new Exception("Can't use File IO stuff in webplayer");
#endif
        }
        public string SaveToBase64()
        {
            using (var stream = new System.IO.MemoryStream())
            {
                SaveToStream(stream);
                stream.Position = 0;
                return System.Convert.ToBase64String(stream.ToArray());
            }
        }
        public static JSONNode Deserialize(System.IO.BinaryReader aReader)
        {
            JSONBinaryTag type = (JSONBinaryTag)aReader.ReadByte();
            switch (type)
            {
                case JSONBinaryTag.Array:
                    {
                        int count = aReader.ReadInt32();
                        JSONArray tmp = new JSONArray();
                        for (int i = 0; i < count; i++)
                            tmp.Add(Deserialize(aReader));
                        return tmp;
                    }
                case JSONBinaryTag.Class:
                    {
                        int count = aReader.ReadInt32();
                        JSONClass tmp = new JSONClass();
                        for (int i = 0; i < count; i++)
                        {
                            string key = aReader.ReadString();
                            var val = Deserialize(aReader);
                            tmp.Add(key, val);
                        }
                        return tmp;
                    }
                case JSONBinaryTag.Value:
                    {
                        return new JSONData(aReader.ReadString());
                    }
                case JSONBinaryTag.IntValue:
                    {
                        return new JSONData(aReader.ReadInt32());
                    }
                case JSONBinaryTag.LongValue:
                    {
                        return new JSONData(aReader.ReadInt64());
                    }
                case JSONBinaryTag.DoubleValue:
                    {
                        return new JSONData(aReader.ReadDouble());
                    }
                case JSONBinaryTag.BoolValue:
                    {
                        return new JSONData(aReader.ReadBoolean());
                    }
                case JSONBinaryTag.FloatValue:
                    {
                        return new JSONData(aReader.ReadSingle());
                    }

                default:
                    {
                        throw new Exception("Error deserializing JSON. Unknown tag: " + type);
                    }
            }
        }

#if USE_SharpZipLib
        public static JSONNode LoadFromCompressedStream(System.IO.Stream aData)
        {
            var zin = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(aData);
            return LoadFromStream(zin);
        }
        public static JSONNode LoadFromCompressedFile(string aFileName)
        {
#if USE_FileIO
            using(var F = System.IO.File.OpenRead(aFileName))
            {
                return LoadFromCompressedStream(F);
            }
#else
            throw new Exception("Can't use File IO stuff in webplayer");
#endif
        }
        public static JSONNode LoadFromCompressedBase64(string aBase64)
        {
            var tmp = System.Convert.FromBase64String(aBase64);
            var stream = new System.IO.MemoryStream(tmp);
            stream.Position = 0;
            return LoadFromCompressedStream(stream);
        }
#else
        public static JSONNode LoadFromCompressedFile(string aFileName)
        {
            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
        }
        public static JSONNode LoadFromCompressedStream(System.IO.Stream aData)
        {
            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
        }
        public static JSONNode LoadFromCompressedBase64(string aBase64)
        {
            throw new Exception("Can't use compressed functions. You need include the SharpZipLib and uncomment the define at the top of SimpleJSON");
        }
#endif

        public static JSONNode LoadFromStream(System.IO.Stream aData)
        {
            using (var R = new System.IO.BinaryReader(aData))
            {
                return Deserialize(R);
            }
        }
        public static JSONNode LoadFromFile(string aFileName)
        {
#if USE_FileIO
            using (var F = System.IO.File.OpenRead(aFileName))
            {
                return LoadFromStream(F);
            }
#else
            throw new Exception("Can't use File IO stuff in webplayer");
#endif
        }
        public static JSONNode LoadFromBase64(string aBase64)
        {
            var tmp = System.Convert.FromBase64String(aBase64);
            var stream = new System.IO.MemoryStream(tmp);
            stream.Position = 0;
            return LoadFromStream(stream);
        }
    } // End of JSONNode

    public class JSONArray : JSONNode, IEnumerable
    {
        private List<JSONNode> m_List = new List<JSONNode>();
        public override JSONNode this[int aIndex]
        {
            get
            {
                if (aIndex < 0 || aIndex >= m_List.Count)
                    return new JSONLazyCreator(this);
                return m_List[aIndex];
            }
            set
            {
                if (aIndex < 0 || aIndex >= m_List.Count)
                    m_List.Add(value);
                else
                    m_List[aIndex] = value;
            }
        }
        public override JSONNode this[string aKey]
        {
            get { return new JSONLazyCreator(this); }
            set { m_List.Add(value); }
        }
        public override int Count
        {
            get { return m_List.Count; }
        }
        public override void Add(string aKey, JSONNode aItem)
        {
            m_List.Add(aItem);
        }
        public override JSONNode Remove(int aIndex)
        {
            if (aIndex < 0 || aIndex >= m_List.Count)
                return null;
            JSONNode tmp = m_List[aIndex];
            m_List.RemoveAt(aIndex);
            return tmp;
        }
        public override JSONNode Remove(JSONNode aNode)
        {
            m_List.Remove(aNode);
            return aNode;
        }
        public override IEnumerable<JSONNode> Childs
        {
            get
            {
                foreach (JSONNode N in m_List)
                    yield return N;
            }
        }
        public IEnumerator GetEnumerator()
        {
            foreach (JSONNode N in m_List)
                yield return N;
        }
        public override string ToString()
        {
            string result = "[ ";
            foreach (JSONNode N in m_List)
            {
                if (result.Length > 2)
                    result += ", ";
                result += N.ToString();
            }
            result += " ]";
            return result;
        }
        public override string ToString(string aPrefix)
        {
            string result = "[ ";
            foreach (JSONNode N in m_List)
            {
                if (result.Length > 3)
                    result += ", ";
                result += "\n" + aPrefix + "   ";
                result += N.ToString(aPrefix + "   ");
            }
            result += "\n" + aPrefix + "]";
            return result;
        }
        public override void Serialize(System.IO.BinaryWriter aWriter)
        {
            aWriter.Write((byte)JSONBinaryTag.Array);
            aWriter.Write(m_List.Count);
            for (int i = 0; i < m_List.Count; i++)
            {
                m_List[i].Serialize(aWriter);
            }
        }
    } // End of JSONArray

    public class JSONClass : JSONNode, IEnumerable
    {
        private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>();
        public override JSONNode this[string aKey]
        {
            get
            {
                if (m_Dict.ContainsKey(aKey))
                    return m_Dict[aKey];
                else
                    return new JSONLazyCreator(this, aKey);
            }
            set
            {
                if (m_Dict.ContainsKey(aKey))
                    m_Dict[aKey] = value;
                else
                    m_Dict.Add(aKey, value);
            }
        }
        public override JSONNode this[int aIndex]
        {
            get
            {
                if (aIndex < 0 || aIndex >= m_Dict.Count)
                    return null;
                return m_Dict.ElementAt(aIndex).Value;
            }
            set
            {
                if (aIndex < 0 || aIndex >= m_Dict.Count)
                    return;
                string key = m_Dict.ElementAt(aIndex).Key;
                m_Dict[key] = value;
            }
        }
        public override int Count
        {
            get { return m_Dict.Count; }
        }


        public override void Add(string aKey, JSONNode aItem)
        {
            if (!string.IsNullOrEmpty(aKey))
            {
                if (m_Dict.ContainsKey(aKey))
                    m_Dict[aKey] = aItem;
                else
                    m_Dict.Add(aKey, aItem);
            }
            else
                m_Dict.Add(Guid.NewGuid().ToString(), aItem);
        }

        public override JSONNode Remove(string aKey)
        {
            if (!m_Dict.ContainsKey(aKey))
                return null;
            JSONNode tmp = m_Dict[aKey];
            m_Dict.Remove(aKey);
            return tmp;
        }
        public override JSONNode Remove(int aIndex)
        {
            if (aIndex < 0 || aIndex >= m_Dict.Count)
                return null;
            var item = m_Dict.ElementAt(aIndex);
            m_Dict.Remove(item.Key);
            return item.Value;
        }
        public override JSONNode Remove(JSONNode aNode)
        {
            try
            {
                var item = m_Dict.Where(k => k.Value == aNode).First();
                m_Dict.Remove(item.Key);
                return aNode;
            }
            catch
            {
                return null;
            }
        }

        public override IEnumerable<JSONNode> Childs
        {
            get
            {
                foreach (KeyValuePair<string, JSONNode> N in m_Dict)
                    yield return N.Value;
            }
        }

        public IEnumerator GetEnumerator()
        {
            foreach (KeyValuePair<string, JSONNode> N in m_Dict)
                yield return N;
        }
        public override string ToString()
        {
            string result = "{";
            foreach (KeyValuePair<string, JSONNode> N in m_Dict)
            {
                if (result.Length > 2)
                    result += ", ";
                result += "\"" + Escape(N.Key) + "\":" + N.Value.ToString();
            }
            result += "}";
            return result;
        }
        public override string ToString(string aPrefix)
        {
            string result = "{ ";
            foreach (KeyValuePair<string, JSONNode> N in m_Dict)
            {
                if (result.Length > 3)
                    result += ", ";
                result += "\n" + aPrefix + "   ";
                result += "\"" + Escape(N.Key) + "\" : " + N.Value.ToString(aPrefix + "   ");
            }
            result += "\n" + aPrefix + "}";
            return result;
        }
        public override void Serialize(System.IO.BinaryWriter aWriter)
        {
            aWriter.Write((byte)JSONBinaryTag.Class);
            aWriter.Write(m_Dict.Count);
            foreach (string K in m_Dict.Keys)
            {
                aWriter.Write(K);
                m_Dict[K].Serialize(aWriter);
            }
        }
    } // End of JSONClass

    public class JSONData : JSONNode
    {
        private string m_Data;
        public override string Value
        {
            get { return m_Data; }
            set { m_Data = value; }
        }
        public JSONData(string aData)
        {
            m_Data = aData;
        }
        public JSONData(float aData)
        {
            AsFloat = aData;
        }
        public JSONData(double aData)
        {
            AsDouble = aData;
        }
        public JSONData(bool aData)
        {
            AsBool = aData;
        }
        public JSONData(int aData)
        {
            AsInt = aData;
        }
        public JSONData(long aData)
        {
            AsLong = aData;
        }

        public override string ToString()
        {
            if (true == IsDoubleQuotes)
                return Escape(m_Data);
                     
            return "\"" + Escape(m_Data) + "\"";
        }

        public override string ToString(string aPrefix)
        {
            return "\"" + Escape(m_Data) + "\"";
        }
        public override void Serialize(System.IO.BinaryWriter aWriter)
        {
            var tmp = new JSONData("");

            tmp.AsInt = AsInt;
            if (tmp.m_Data == this.m_Data)
            {
                aWriter.Write((byte)JSONBinaryTag.IntValue);
                aWriter.Write(AsInt);
                return;
            }
            tmp.AsLong = AsLong;
            if (tmp.m_Data == this.m_Data)
            {
                aWriter.Write((byte)JSONBinaryTag.LongValue);
                aWriter.Write(AsLong);
                return;
            }
            tmp.AsFloat = AsFloat;
            if (tmp.m_Data == this.m_Data)
            {
                aWriter.Write((byte)JSONBinaryTag.FloatValue);
                aWriter.Write(AsFloat);
                return;
            }
            tmp.AsDouble = AsDouble;
            if (tmp.m_Data == this.m_Data)
            {
                aWriter.Write((byte)JSONBinaryTag.DoubleValue);
                aWriter.Write(AsDouble);
                return;
            }

            tmp.AsBool = AsBool;
            if (tmp.m_Data == this.m_Data)
            {
                aWriter.Write((byte)JSONBinaryTag.BoolValue);
                aWriter.Write(AsBool);
                return;
            }
            aWriter.Write((byte)JSONBinaryTag.Value);
            aWriter.Write(m_Data);
        }
    } // End of JSONData

    internal class JSONLazyCreator : JSONNode
    {
        private JSONNode m_Node = null;
        private string m_Key = null;

        public JSONLazyCreator(JSONNode aNode)
        {
            m_Node = aNode;
            m_Key = null;
        }
        public JSONLazyCreator(JSONNode aNode, string aKey)
        {
            m_Node = aNode;
            m_Key = aKey;
        }

        private void Set(JSONNode aVal)
        {
            if (m_Key == null)
            {
                m_Node.Add(aVal);
            }
            else
            {
                m_Node.Add(m_Key, aVal);
            }
            m_Node = null; // Be GC friendly.
        }

        public override JSONNode this[int aIndex]
        {
            get
            {
                return new JSONLazyCreator(this);
            }
            set
            {
                var tmp = new JSONArray();
                tmp.Add(value);
                Set(tmp);
            }
        }

        public override JSONNode this[string aKey]
        {
            get
            {
                return new JSONLazyCreator(this, aKey);
            }
            set
            {
                var tmp = new JSONClass();
                tmp.Add(aKey, value);
                Set(tmp);
            }
        }
        public override void Add(JSONNode aItem)
        {
            var tmp = new JSONArray();
            tmp.Add(aItem);
            Set(tmp);
        }
        public override void Add(string aKey, JSONNode aItem)
        {
            var tmp = new JSONClass();
            tmp.Add(aKey, aItem);
            Set(tmp);
        }
        public static bool operator ==(JSONLazyCreator a, object b)
        {
            if (b == null)
                return true;
            return System.Object.ReferenceEquals(a, b);
        }

        public static bool operator !=(JSONLazyCreator a, object b)
        {
            return !(a == b);
        }
        public override bool Equals(object obj)
        {
            if (obj == null)
                return true;
            return System.Object.ReferenceEquals(this, obj);
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return "";
        }
        public override string ToString(string aPrefix)
        {
            return "";
        }

        public override int AsInt
        {
            get
            {
                JSONData tmp = new JSONData(0);
                Set(tmp);
                return 0;
            }
            set
            {
                JSONData tmp = new JSONData(value);
                Set(tmp);
            }
        }
        public override long AsLong
        {
            get
            {
                JSONData tmp = new JSONData((long)0);
                Set(tmp);
                return 0;
            }
            set
            {
                JSONData tmp = new JSONData(value);
                Set(tmp);
            }
        }
        public override float AsFloat
        {
            get
            {
                JSONData tmp = new JSONData(0.0f);
                Set(tmp);
                return 0.0f;
            }
            set
            {
                JSONData tmp = new JSONData(value);
                Set(tmp);
            }
        }
        public override double AsDouble
        {
            get
            {
                JSONData tmp = new JSONData(0.0);
                Set(tmp);
                return 0.0;
            }
            set
            {
                JSONData tmp = new JSONData(value);
                Set(tmp);
            }
        }
        public override bool AsBool
        {
            get
            {
                JSONData tmp = new JSONData(false);
                Set(tmp);
                return false;
            }
            set
            {
                JSONData tmp = new JSONData(value);
                Set(tmp);
            }
        }
        public override JSONArray AsArray
        {
            get
            {
                JSONArray tmp = new JSONArray();
                Set(tmp);
                return tmp;
            }
        }
        public override JSONClass AsObject
        {
            get
            {
                JSONClass tmp = new JSONClass();
                Set(tmp);
                return tmp;
            }
        }
    } // End of JSONLazyCreator

    public static class JSON
    {
        public static JSONNode Parse(string aJSON)
        {
            return JSONNode.Parse(aJSON);
        }
    }
}


by 널부러 2013. 12. 3. 12:51
=== UDP 서버
#include "stdafx.h"
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>

#define PORT 65000
#define BUFMAX 255

struct dataStruct
{
    int intValue;
    char charValue[100];
    float floatValue;
};

void ErrorMessage(char *errorMessage)  /* External error handling function */
{
    printf("%s\n", errorMessage);
    exit(1);
}

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsaData;               

    SOCKET sock;
    SOCKADDR_IN echoServAddr;
    SOCKADDR_IN echoClntAddr;
                        
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
    {
        fprintf(stderr, "WSAStartup() failed");
        exit(1);
    }

    /* Create socket for sending/receiving datagrams */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
        ErrorMessage("socket() failed");

    /* Construct local address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));
    echoServAddr.sin_family = AF_INET;
    echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    echoServAddr.sin_port = htons(PORT);

    /* Bind to the local address */
    if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) != 0)
        ErrorMessage("bind() failed");

    for (;;) /* Run forever */
    {
        char echoBuffer[BUFMAX];
        int cliLen = sizeof(echoClntAddr);
        int recvMsgSize = recvfrom(sock, echoBuffer, BUFMAX, 0, (struct sockaddr*) &echoClntAddr, &cliLen);
        if (recvMsgSize < 0)
            ErrorMessage("recvfrom() failed");

        dataStruct recvData;
        memcpy(&recvData, echoBuffer, sizeof(recvData));
        printf("RecvData - %d, %s, %f\n", recvData.intValue, recvData.charValue, recvData.floatValue);

        dataStruct sendData;
        ZeroMemory(&sendData, sizeof(sendData));
        sendData.intValue = 101;
        sprintf(sendData.charValue, "잘받음");
        sendData.floatValue = 12.11f;

        char sendBuf[BUFMAX];
        ZeroMemory(sendBuf, sizeof(sendBuf));
        memcpy(sendBuf, &sendData, sizeof(sendData));

        if (sendto(sock, sendBuf, sizeof(sendData), 0, (struct sockaddr *) &echoClntAddr, sizeof(echoClntAddr)) == 0)
        {
            ErrorMessage("sendto() send Error");
        }
    }

    return 0;
}
=== php 클라이언트
<?php
    class CDataClass
    {
        private $intValue;
        private $charValue;
        private $floatValue;
       
        public function SetDataInt($int)
        {
            $this->intValue = $int;
        }
       
        public function &GetDataInt()
        {
            return $this->intValue;
        }
       
        public function SetDataChar($char)
        {
            $this->charValue = $char;
        }
       
        public function &GetDataChar()
        {
            return $this->charValue;
        }
       
        public function SetDataFloat($float)
        {
            $this->floatValue = $float;
        }
       
        public function &GetDataFloat()
        {
            return $this->floatValue;
        }
       
        public function PackData()
        {
            $temp = pack("i", $this->intValue);
            $temp .= pack("a100", $this->charValue);
            $temp .= pack("f", $this->floatValue);

            return $temp;
        }
       
        public function UnpackData($value)
        {
            $array = unpack("iInt/a100Char/fFloat", $value);
           
            $this->intValue = $array[Int];
            $this->charValue = $array[Char];
            $this->floatValue = $array[Float];
        }
    }

define("_IP",    "127.0.0.1");
define("_PORT",  "65000");

$sendData = new CDataClass();
$sendData->SetDataInt(100);
$sendData->SetDataChar("아햏햏");
$sendData->SetDataFloat(10.1);

$temp1 = $sendData->GetDataInt();
$temp2 = $sendData->GetDataChar();
$temp3 = $sendData->GetDataFloat();
echo "CLIENT >> send Data - $temp1 , $temp2 , $temp3 
"; $sendbuf = $sendData->PackData(); $sendlen = strlen($sendbuf); $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_sendto($sock, $sendbuf, $sendlen, 0, _IP, _PORT); $from = ''; $port = 0; $recvSize = socket_recvfrom($sock, $buf, 4096, 0, $from, $port); $recvData = new CDataClass(); $recvData->UnpackData($buf); $temp1 = $recvData->GetDataInt(); $temp2 = $recvData->GetDataChar(); $temp3 = $recvData->GetDataFloat(); socket_close($sock); echo "CLIENT >> recv Data - $temp1 , $temp2 , $temp3
"; ?>
by 널부러 2013. 10. 1. 18:46
#include "stdafx.h"

#include <iostream>
#include <regex>
#include <fstream>

#include "errorDefine.h"

int _tmain(int argc, _TCHAR* argv[])
{
    std::ifstream openFile;
    openFile.open("errorDefine.h");

    if( !openFile.is_open() )
    {
        return 0;
    }
   
    // 파싱할 내용
    std::regex startEndRegex( "[{}]" );
    std::regex indexRegex ("(-?[0-9]+),[^0-9]");
    std::regex defineRegex ("[0-9a-zA-Z_]+");
    std::regex logMessageRegex("// ");

    int index = 0;
    bool startPrint = false;
    while( openFile.good() )
    {
        std::string stringLine;
        std::string defineString;
        std::string logMessage;

        std::smatch indexMatch;
        std::smatch defineMatch;
        std::smatch logMessageMatch;
        std::smatch startEndMatch;

        // 파일 읽기
        std::getline( openFile, stringLine );

        // 공백 체크
        stringLine.erase( stringLine.find_last_not_of(' ') + 1 );
        if( 0 == stringLine.length()  )
            continue;
       
        // 시작 끝 체크
        if( true == std::regex_search(stringLine, startEndMatch, startEndRegex) )
        {
            startPrint = !startPrint;
            continue;
        }

        // 출력 여부 확인
        if( false == startPrint )
            continue;
   
        // define 인덱스 출력
        std::regex_search(stringLine,indexMatch,indexRegex);
        if( !indexMatch.empty() )
        {   
            std::string tempIndex = indexMatch[0];
            index = atoi( tempIndex.c_str() );
        }
        else
        {
            index++;
        }

        // define Name
        std::regex_search(stringLine, defineMatch, defineRegex);
        if( !defineMatch.empty() )
        {
            defineString = defineMatch[0];
        }

        // define 메시지
        std::regex_search(stringLine, logMessageMatch,logMessageRegex);
        if( !logMessageMatch.empty()  )
        {
            logMessage = logMessageMatch[0].second._Ptr;
        }
        else
        {
            logMessage = "***메시지가 없음 추가요망";
        }

        // 출력
        printf("index : %5d - defineName : %s - message : %s\n", index, defineString.c_str(), logMessage.c_str() );
    }

    return 0;
}
=== errorDefine.h
enum errorType
{
    RESULT_FAIL = -1,       // 에러
    RESULT_OK,              // 정상

    ERROR_1,                // 에러 메시지 출력(1번이에용)
    ERROR_2,                // 에러 메시지 출력(2번이에용)
    ERROR_3,           	    //
    ERROR_4 = 100,          // 중간에 변경된 번호야

    ERROR_TYPE_MAX,         // 에러 번호 끝
};
by 널부러 2013. 5. 3. 18:41

boost에서 xml, ini, json, info 확장자 파일을 쉽게 파싱 할수 있는데 그것이  property_tree ...

그중에서 젤 많이 쓰는 ini 파일 파싱 하는 코드를 올려본다.

- test.ini 파일 내용

[Section]
Value1 = text_string
Value2 = 10

- 소스 코드

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

int _tmain(int argc, _TCHAR* argv[])
{
	// ptree 선언
	boost::property_tree::ptree pt;

	// 파일 읽어오기 
	boost::property_tree::ini_parser::read_ini( "test.ini", pt );
	
	// 문자열 읽기
	std::string value1 = pt.get<std::string>("Section.Value1");

	// 숫자 읽기 
	int value2 = pt.get<int>("Section.Value2");

	return 0;
}



by 널부러 2013. 4. 22. 15:02

mysql 저장 디렉토리를 변경 할때 참고하라

윈도우 호환 때문에 samba로 마운트 한 데이터는 퍼미션 설정을 할수 없어서 에러가 나는거 같다 -_-;

그래서 nfs로 NAS를 마운트 해서 해결 하는수 밖게 없는거 같다..

왜 그런지는 퍼미션 문제일꺼라고 추측 되지면 정확한건 모르겠다..

다행이 아파치는 samba로 마운트 한 폴더도 별 문제는 없는거 같다..


by 널부러 2013. 3. 23. 23:09

bind, function 간단 사용 방법

boost, tr1 다 설명...



// bind 할 함수 
int sum( int a , int b )
{
	return a+b;
}

// boost bind 사용
// _1, _2 는 입력 인자
#include <boost/bind.hpp>

boost::bind( &sum, _1, _2 );

// tr1 bind 사용
// boost와는 다르게 인자를 쓸려면 std::tr1::placeholders 사용 해야함.
#include <functional>

std::tr1::bind( &sum, std::tr1::placeholders::_1, std::tr1::placeholders::_2 );

///////////////////////////////////////////////////////////////////////////////////////////////

// bind 한 함수를 담는 boost::function
#include <boost/function.hpp>

boost::function< int(int, int) > temp = boost::bind( &sum, _1, _2 );

// bind 한 함수를 담는 std::tr1::function
#include <functional>

std::tr1::function< int(int, int) > temp = std::tr1::bind( &sum, std::tr1::placeholders::_1, std::tr1::placeholders::_2 );

///////////////////////////////////////////////////////////////////////////////////////////////

// bind class 처리 - tr1 도 똑같아용....
class boostBind
{
private:
	std::vector< boost::function< int( int, int ) > > m_funcArray;	// 바인딩 한 함수를 모으기 위한 vector

public:
	boostBind() 
	{
		m_funcArray.push_back( boost::bind( &boostBind::sum, this, _1, _2 ) );
		m_funcArray.push_back( boost::bind( &boostBind::sub, this, _1, _2 ) );
	}
	~boostBind() {}

	int sum( int a , int b )
	{
		return a+b;
	}

	int sub( int a , int b )
	{
		return a-b;
	}

	void run()
	{
		// 덧셈 함수 호출
		int temp1 = m_funcArray[0]( 100, 200 );

		// 뺄셈 함수 호출 
		int temp2 = m_funcArray[1]( 200, 100 );
	}
};
by 널부러 2012. 10. 30. 19:26

어떤 자료형이든 다 넣을수 있는 그런 컨테이너...

사용법은 아래와 같다...

그런데 이건 어디다 써먹으면 좋을까? 잘모르겠지만 일단 정리...

#include <boost/any.hpp>

int main()
{
	boost::any all;
	
	// 아래와 같이 넣으면 int형으로 변경 
	// 값만 써도 알아서 인식하지만 확실하게 어떤 자료형이 들어갔는지 알기 위해 
	all = (int)100;
	
	// 이상태에서는 자료형은 안바뀌고 값만 갱신
	all = 200;

	// 여기서 다른 자료형으로 데이터를 넣으면 자료형도 변경 되면서 데이터 갱신
	all = (float)1.3f;

	// 값을 꺼내는 방법 첫번째 -  타입을 비교 하고 맞을때 값 꺼내기 
	if( all.type() == typeid(float) )
	{
		float &output = boost::any_cast<float &>(all);
	}

	// 값을 꺼내는 방법 두번째 -  try catch 문을 사용 해서 꺼내기 
	// 여기서는 실패에서 에러 나겠죵...
	try
	{
		int &otput = boost::any_cast<int &>(all);
	}
	catch(const boost::bad_any_cast &e)
	{
		printf("%s\n", e.what() );
	}
	
	// 변수 초기화는 요렇게???
	all = boost::any();

	if( all.empty() )
	{
		printf("아무것도 없네요\n");
	}
	
	return 0;
}


by 널부러 2012. 10. 18. 13:40

이거 쓰면 Thread를 그룹으로 묶어서 쓸수 있심..

사용법은 아래 보셈..

#include "boost/thread.hpp"

class threadFunc
{
    int m_a;
public:
    threadFunc( int a )
    {
        m_a = a;
    }

    void operator()()  
    {  
        printf("[%d]일단 들어왔네!!! [%d]\n", boost::this_thread::get_id(), m_a );

        Sleep(5000);

        printf("[%d] 끝났네 [%d]\n", boost::this_thread::get_id(), m_a );
    }  
};

int main()
{
    boost::thread_group tg;

    tg.create_thread( threadFunc(1) );                        // 1번 스래드 생성 
    tg.add_thread(new boost::thread( threadFunc(2) ) );        // 2번 스래드 생성 
    tg.add_thread(new boost::thread( threadFunc(3) ) );        // 3번 스래드 생성 

    //모든 스래드가 종료 될때까지 대기 
    tg.join_all();

    return 0;
}

by 널부러 2012. 10. 16. 22:36

문자를 숫자로 or 숫자를 문자로 바꿀때 사용 한다.

사용법은 간단하다.. 아래보셈..

#include "boost/lexical_cast.hpp"

int main()
{
    std::string input = "1";
    int output = 0;

    try
    {
        convertDta = boost::lexical_cast<int>( inputValue );
    }
    catch(boost::bad_lexical_cast &e)
    {
        // 변경이 안되면 아래 에러 출력
        printf("%s\n", e.what() );
        return false;
    }

    return 0;
}

그런데 이거 잘 써먹지는 못할듯..

문제가 2가지가 있심.. BYTE(unsigned char) 변환이 잘 안된다는거 하고

atoi(itoa), stringstream 등으로 변환하는거보단 촐랭 느리다는거...

아무튼 오늘도 뭔가 하나 올림..



by 널부러 2012. 10. 16. 21:38
| 1 2 3 4 5 |