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
잊어먹을까봐 써둔다..

core dump <- 덤프 파일이라는 gdb로 내용을 볼수 있다고 하는데 어떻게 하는지 알아내자..
ulimit <- 덤프 뜨기 위해 os에서 설정..
crontab <- 스케줄러... 자세한거 조사하자

덤프 뜨면서 데이터 보고 싶으면 gcc 컴파일 할때도 옵션 줘야한다. -g3 -O0 옵션 관련 해서도 조사하자...


by 널부러 2010. 3. 9. 12:30
출처  : http://muse.incheon.ac.kr/jschae/gcc_gdb.html

g++, gdb 사용법 


□ g++ 사용법

  • 일반적인 컴파일

    > g++ filename

    ⇒ filename이라는 파일을 컴파일하고 오류가 없을 경우 실행 파일 a.out을 생성
     
  • 실행 파일을 지정하는 컴파일

    > g++ -o exefile filename

    ⇒ filename이라는 파일을 컴파일하여 실행파일 exefile 생성
     
  • gdb를 사용하여 디버그할 때의 컴파일

    > g++ -g filename

    ⇒ filename이라는 파일을 컴파일하여 실행 파일 a.out을 생성하고 gdb로 디버그함
     
  • 실행 파일을 지정하여 gdb로 디버그할 때의 컴파일

    > g++ -o exefile -g filename

    ⇒ filename이라는 파일을 컴파일하여 실행 파일 exefile을 생성하고 gdb로 디버그함

□ gdb 사용법

  • gdb 실행

    > gdb exefile

    ⇒ 실행 파일 exefile을 디버그함 (실행 파일은 반드시 -g 옵션을 사용하여 컴파일되어야 함)
     
  • gdb 명령어 

명령어

의  미

b (breakpoint)

실행 중 디버그를 위해 멈추는 위치 지정

b 함수명

함수명에서 멈춤

b 라인번호

라인번호에서 멈춤

r (run)

실행 시작

n (next)

현재 라인 실행 (함수의 경우 실행하고 다음 라인으로 넘어 감)

s (step)

현재 라인 실행 (함수의 경우 호출된 함수 내로 들어가 실행 계속)

c (continue)

다음 breakpoint까지 실행

l (list)

현재 수행되고 있는 라인부터 10개 라인씩 연속적으로 소스 코드를 프린트

p (print) 변수명

변수명으로 저장되어 있는 내용을 프린트

h (help)

도움말

q (quit)

gdb 종료


by 널부러 2009. 12. 31. 00:40

Windows가 @#!^!%!@#$%!@.exe에서 중단점을 트리거했습니다.

힙이 손상되었거나 @#!^!%!@#$%!@.exe 또는 여기서 로드한 DLL에 버그가 있을 수도 있습니다.

자세한 진단 정보는 [출력] 창을 참조하십시오.

---------------------------------------------------------------------------------------
위와 같은 에러가 난다면 보통 DLL에서 동적 메모리 생성한걸 Exe에서 삭제하거나
그 반대 경우에 발생하는 에러이다

하지만 DLL를 쓰지 않은 상황에서 에러가 난다면 다음 상황을 먼저 생각하라

나는 lib라이브러리를 사용하여 exe프로젝트를 생성했는데 위와 같은 에러가 발생했다..

에러의 원인은 동적으로 할당한 크기보다 더 크게 초기화를 하는 작업을 하여 할당한 크기보다 힙을 더 사용한 상황이고
그런 상황에서 삭제를 하면서 저런 에러가 발생했다..

다시 정리하자면 동적으로 할당한 메모리 크기가 10이라고 하면
초기화(Zeromemory 함수 사용)할때 20으로 초기화 하고
삭제를 하면서 발생한 문제이다.

고로 DLL(혹은 lib)쪽 에러를 의심하기 전에 초기화를 할당한 크기만큼 제대로 초기화 하고
삭제 했는지 확인해보자
!!!

이 에러를 잡아주신 회사 실장님에게 감사드리며...

에러 원인을 알았을때 좀 쪽팔렸다..

아무튼 프로그램의 보통 큰 원인은 이런 단순 실수로 발생하는게 많으니 앞으로 주의하며 코딩해야겠다 ㅠ.ㅠ






by 널부러 2009. 8. 21. 12:08
에 정말 할줄 몰라서 정말 애먹었네 -_-
아무튼 처리한방법에 대해서 일단 정리해 둔다.

일단 svn 서버 파일을 받아야 한다.
Subversion 다운로드 경로 : http://subversion.tigris.org/ (설치 파일 찾을려면 좀 뒤저야 한다.)
Subversion Manager 다운로드 경로 : http://www.pyrasis.com/ (메인 화면에 바로 있다.)

일단 2개의 파일을 받으면 먼저 Subversion을 설치 한다.
그 다음에 Subversion Manager를 설치 한다.

설치하고 나면 저장소를 만들어야 하는데 command 명령으로 아래와 같이 입력 해주자.
아래와 같이 저장소를 만들면 파일시스템으로 저장한다.
(버클리 DB를 이용할라면 svnadmin create --fs-type bdb sample 실행해줘야한다.)
C:\Documents and Settings\Administrator>cd \

c:\>mkdir repos

c:\>cd repos

c:\repos>svnadmin create sample
그럼 폴더가 sample 폴더에 저장소가 생긴다.
그럼 권한 설정이나 이런걸 해줘야한다.
생성한 저장소 폴더 하위 폴더중에 conf 폴더가 있다.
그럼 authz, passwd, svnserve.conf 3개의 파일이 있는데 세팅을 바꿔줘야한다.

먼저 svnserve.conf 파일을 열어보면 아래와 같은 세팅이 되어있다.
초기에 아래내용은 다 #으로 주석 처리 되어있다 풀어주어야 원하는데로 세팅 가능하다.
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
realm = sample Repository
#익명의 사용자 접근을 막는다.
#접근 가능한 사용자는 쓰기 권한을 준다.
#접근 가능 계정 목록과 비밀번호 관리하는 파일명
#경로 기반 접근 제어를 위한 인증 규칙을 설정하는 파일명
#저장소 이름(프로젝트가 여러개면 꼭 바꿔주자 UID 역활함)

계정을 만든다면 passwd 파일을 열어서 아래와 같이 넣어주자
계정 = 비밀번호
예) test = 1111

authz 파일은 계정의 폴더 접근 권한을 세팅하는데 이건 생략한다.

세팅이 끝나면 매니저를 실행해서 폴더 위치를 설정해주고 Start로 실행하면 된다
(자세한 설명은 http://www.pyrasis.com/ 가면 볼수 있다.)

서버는 세팅이 끝났으면 클라이언트 깔아서 접속하면 된다..
하는 방법은 그닥 어렵지 않으니 클라이언트 설명은 생략한다...
(메뉴도 한글로 나오니 좀 삽질 해보면 답나옴..)
by 널부러 2009. 5. 22. 15:44

에... 혹시 압축하는 일이 있으면 이걸 사용 하면 된다.

zlib 1.2.3 버전 (출처 : http://www.zlib.net/ )

프로젝트 속성에서 ( C/C++ -> 코드 생성 -> 런타임 라이브러리) 설정은
각 컴파일 상태에 따라 세팅 해주어야 합니다.
그래야 충돌 메시지가 나오지 않습니다.

debug   컴파일 : 다중 스레드 디버그(/MTd)
release 컴파일 : 다중 스레드(/MT)

- 기본 파일
zlib.lib  <- Visual Studio 2005에서 LIB Release 컴파일한 lib 파일
zlibd.lib <- Visual Studio 2005에서 LIB Debug 컴파일한 lib 파일
zconf.h   <- minigzip 프로젝트의 헤더파일
zlib.h    <- minigzip 프로젝트의 헤더파일
vc80.pdb  <- debug로 컴파일시 없으면 link4099 에러남..
vc80.idb  <- debug로 컴파일시 없으면 link4099 에러남..

- 내가 만든 파일 - 압축 함수를 class로 구성한것밖게 없음...
zlibManager.cpp 
zlibManager.h

샘플코드는 귀찮아서 안만들련다..
CZlibmanager 클레스에 보면 함수가 딱 2가지 있는데..
그거 사용 하면 된다... 어렵지 않으니까 그냥 쓰면 될듯...

link4099 에러 나는것때문에 pdb,idb 파일을 넣어뒀다...
솔직히 무시해도 되는 에러인데 링크에러는 pragma를 이용해서는 무시가 되지 않는다. -_-;
(참 그지같아 MS 링크 에러도 막아줘야 할꺼 아냐 -_-;)

아무튼 필요하면 쓰기 바란다...

by 널부러 2009. 5. 21. 18:01
유니코드와 멀티코드(안시코드)를 쉽게 바꿀때 사용 하는 USES_CONVERSION 매크로가 있는데
사용할때 #include <atlconv.h> 링크 하고 아래와 같이 사용하면 된다.
#include <atlconv.h>

USES_CONVERSION;

TCHAR widechar[]=L"sample";
char ansichar[10];
ansi = W2A(widechar);

하지만 간혹 헤더만 링크 시키고 아래와 같은 에러가 발생할때가 있다.
 1>xxxxx.obj : error LNK2001: "unsigned int (__stdcall* ATL::g_pfnGetThreadACP)(void)" (?g_pfnGetThreadACP@ATL@@3P6GIXZA) 외부 기호를 확인할 수 없습니다.

이런 에러가 발생할 경우에는 라이브러리 파일이 링크가 안되서 발생하는 문제이다
아래와 같이 라이브러리 파일을 링크 해주면 된다.
#pragma comment (lib, "atls.lib")


by 널부러 2009. 4. 20. 17:39
에 템플릿을 사용하면서 발생하는 문제가 생겨서 정리 해본다.

template < class T >
calss test
{
     std::queue< T > m_queue;
     T Pop()
     {
        if( m_Queue.empty() )
            return NULL;

        T data = m_Queue.front();
        m_Queue.pop();
        return data;
    }
}

예를 들어 위와 같은 template가 있다고 치자
그래서 아래와 같이 사용한다.
 int temp;
test<int> val;
temp = val.pop();
이런식으로 정적인 자료형을 선언 하면 값을 받아오는것이 가능하다
위에서는 queue에 값을 넣은게 없으니 그냥 NULL 값을 받을것이다.

하지만 문제가 되는건 아래와 같은 상황이다
 struct testTemplet
{
     int a;
     int b;
}

testTemplet temp;
test<testTemplet> val;
temp = val.pop();
코드상으로는 이상이 없어보이지만 컴파일러에서는 에러가 발생한다.

컴파일러 에러 내용은 아래와 같다.
 원인: 'int'에서 'const testTemplet'(으)로 변환할 수 없습니다.
소스 형식을 가져올 수 있는 생성자가 없거나 생성자 오버로드 확인이 모호합니다.

에러원인으로 생각되는것은 구조체형은 NULL이라는 값을 알수가 없기에 발생하는 문제이다.
동적으로 생성한다면 이와 같은 문제는 발생하지 않는다.
하지만 정적일 경우에는 위와 같은 코드로는 프로그램을 작성할수가 없다

일단 임시 방편으로 값을 받아오는 방법을 바꾸서 처리하니 해결은 되었지만 뭔가 그리 깔끔하지 않은거 같아 찝찝하긴 하다
아래는 내가 해결한 방법에 대해서 적어보겠다.
 template < class T >
calss test
{
     std::queue< T > m_queue;
     bool Pop( T& data )
     {
        if( m_Queue.empty() )
            return false;

        data = m_Queue.front();
        m_Queue.pop();
        return true;
    }
}

 struct testTemplet
{
     int a;
     int b;
}

testTemplet temp;
test<testTemplet> val;
if( true == val.pop( temp ))
{
    printf("정상적으로 값을 받음");
}
else
{
    printf("값을 받지 못했음");
}

이방법 말고 해결 방법이 있다면 누가 좀 알려주기 바란다.


by 널부러 2009. 3. 26. 16:23
음 이것에 관련해서는 온라인서버제작모임에 명예의전당에 올라온 "Ciritical Section을 이용한 동기화 처리법"
을 보고 좀 고민하다가 리플에 GPG에 관련 또 글이 있어서 그거보고 제가 초금 개조 해봤습니다..

GPG에서 참고 한 글 링크 : http://www.gpgstudy.com/forum/viewtopic.php?t=10593
코딩할때 참고 한 글 링크 : http://ricanet.com/new/view.php?id=blog/050807
                                     http://ricanet.com/new/view.php?id=blog/050811a

class는 CCriticalSection 과 CSynchronized 2가지를 이용합니다.
 class CCriticalSection
{
private:
    CRITICAL_SECTION m_cs;

public:
    CCriticalSection(void)
    {
        ::InitializeCriticalSection( &m_cs );
    }
   
    virtual ~CCriticalSection(void)
    {
        ::DeleteCriticalSection( &m_cs );
    }

    void Lock(void)
    {
        ::EnterCriticalSection( &m_cs );
    }

    void Unlock(void)
    {
        ::LeaveCriticalSection( &m_cs );
    }
};

 class CSynchronized
{
private:
    CCriticalSection* m_pLock;

public:
    CSynchronized(CCriticalSection* _pLock) : m_pLock(_pLock)
    {
        m_pLock->Lock();
    }

    virtual ~CSynchronized(void)
    {
        m_pLock->Unlock();
    }

    operator bool()
    {
        return false;
    }
};

그리고 좀 깔끔하게 쓰기 위해서 define을 사용 하는데 아래와 같습니다.
 #define SYNCHRONIZED_BLOCK(CSif(CSynchronized _lock = CS) {} else   

자 이것에 대한 설명을 하자면
CriticalSection을 사용하다보면 EnterCriticalSection()걸고 LeaveCriticalSection()를 실행하지 않아 데드락에 빠지는
상황이 발생 할수 있습니다. 그것을 코드적으로 방지 하기 위해 생성자와 소멸자를 이용해서 만든것이 CCriticalSection 과 CSynchronized 입니다.


일단 간단하게 사용 방법을 설명하자면 아래와 같이 class에 CriticalSection을 상속 받습니다.
 class CTest :public CCriticalSection
{
public:
    CTest(void);
    ~CTest(void);

    char temp[128];
};

CriticalSection을 이용 할때는 아래와 같이 사용합니다.

CTest
test;                                                          // 변수 선언

{
     CSynchronized sync( &test );                           // EnterCriticalSection 실행

     sprintf( test.temp, "테스트 아햏햏");                   //  작업
     printf("%s\n", test.temp);
}                                                                       // LevelCriticalSection 실행


하지만 위와 같은 방식은 코드를 보기에 뭔가 좀 직관적이지 않아서 (직관적이지 않다는것은 중괄호 안에 Lock를 사용한다고
선언하는것을 말함) Define을 사용해서 요것을 좀 바꿔본것입니다.
 
CTest
test;                                                          // 변수 선언

SYNCHRONIZED_BLOCK( &test )                          // EnterCriticalSection 실행
{
     sprintf( test.temp, "테스트 아햏햏");                   //  작업
     printf("%s\n", test.temp);
}                                                                       // LevelCriticalSection 실행


by 널부러 2009. 3. 11. 18:03
| 1 2 3 |