protected override void OnBeginObject() { //create new Object PushCurrentState(); //enter new state : create new element, and set to current object _currentObject = _currentElement = _doc.CreateElement(""); //expected key name _state = ParsingState.ExpectKeyName; }
static byte[] TestGenLqDocStream() { LiquidDoc doc = new LiquidDoc(); var elem = doc.CreateElement("user_info"); doc.DocumentElement = elem; elem.AppendAttribute("first_name", "A"); elem.AppendAttribute("last_name", "B"); elem.AppendAttribute("age", 20); //test native array object elem.AppendAttribute("memberlist1", new string[] { "x", "y", "z" }); elem.AppendAttribute("memberlist2", new object[] { 1, "y", "z" }); Dictionary <string, int> memberlist3 = new Dictionary <string, int>(); memberlist3.Add("score1", 10); memberlist3.Add("score2", 20); memberlist3.Add("score3", 30); memberlist3.Add("score4", 40); elem.AppendAttribute("memberlist3", memberlist3); List <int> memberlist4 = new List <int>() { 1, 2, 3, 4, 5 }; elem.AppendAttribute("memberlist4", memberlist4); byte[] output = null; using (var ms = new MemoryStream()) { var ser = new LiquidSerializer(); var binWriter = new BinaryWriter(ms); ser.SetBinaryWriter(binWriter); ser.WriteDocument(doc); output = ms.ToArray(); ms.Close(); } return(output); //using (var ms = new MemoryStream(output)) //{ // var docDeser = new LiquidDocumentDeserializer(); // var reader = new BinaryReader(ms); // docDeser.SetBinaryReader(reader); // docDeser.ReadDocument(); // LiquidDoc result = docDeser.Result; //} }
public static LiquidElement Parse(char[] sourceBuffer, bool reformat) { //#if DEBUG // debugDataFormatParserLog dbugDataFormatParser = null; // if (dbug_EnableLogParser) // { // dbugDataFormatParser = new debugDataFormatParserLog(); // dbugDataFormatParser.Begin("json_" + dbug_file_count + " "); // dbug_file_count++; // dbugDataFormatParser.WriteLine(new string(sourceBuffer)); // } //#endif Stack <object> myVElemStack = new Stack <object>(); Stack <string> myKeyStack = new Stack <string>(); object currentObj = null; StringBuilder myBuffer = new StringBuilder(); string lastestKey = ""; int currentState = 0; int j = sourceBuffer.Length; bool isDoubleNumber = false; bool isSuccess = true; bool isInKeyPart = false; LiquidDoc doc = new LiquidDoc(); if (sourceBuffer == null) { return(LiquidElementHelper.CreateXmlElementForDynamicObject(doc)); } //WARNING: custom version, about ending with comma //we may use implicit comma feature, //in case we start new line but forget a comma, //we auto add comma bool implicitComma = false; char openStringWithChar = '"'; int i = 0; //int hexdigiCount = 0; //char hex00 = '\0'; //char hex01 = '\0'; //char hex02 = '\0'; //char hex03 = '\0'; for (i = 0; i < j; i++) { if (!isSuccess) { //#if DEBUG // if (dbug_EnableLogParser) // { // dbugDataFormatParser.IndentLevel = myKeyStack.Count; // dbugDataFormatParser.WriteLine("fail at pos=" + i + " on " + currentState); // } //#endif break; } //-------------------------- char c = sourceBuffer[i]; //#if DEBUG // if (dbug_EnableLogParser) // { // dbugDataFormatParser.WriteLine(i + " ," + c.ToString() + "," + currentState); // } //#endif //-------------------------- switch (currentState) { case 0: { if (c == '{') { currentObj = doc.CreateElement("!j"); currentState = 1; isInKeyPart = true; myBuffer.Length = 0; //clear } else if (c == '[') { currentObj = new LqArray(); currentState = 5; isInKeyPart = false; myBuffer.Length = 0; } else if (char.IsWhiteSpace(c)) { continue; } else { isSuccess = false; NotifyError(); break; } } break; case 1: { if (c == '"' || c == '\'') { openStringWithChar = c; currentState = 2; } else if (char.IsWhiteSpace(c)) { continue; } else if (c == '}') { if (currentObj is LiquidElement) { if (myVElemStack.Count > 0) { object velem = myVElemStack.Pop(); if (velem is LiquidElement) { lastestKey = myKeyStack.Pop(); AddVElement((LiquidElement)velem, lastestKey, currentObj); currentObj = velem; } else if (velem is LiquidArray) { AddVElement((LiquidArray)velem, currentObj); currentObj = velem; currentState = 7; isInKeyPart = false; } } } else { NotifyError(); isSuccess = false; } } else if (char.IsLetter(c) || c == '_') { myBuffer.Append(c); currentState = 9; } else { NotifyError(); isSuccess = false; break; } } break; case 2: { if (c == '\\') { currentState = 3; } else if (c == openStringWithChar) { if (isInKeyPart) { lastestKey = myBuffer.ToString(); currentState = 4; myBuffer.Length = 0; //clear } else { if (currentObj is LiquidArray) { object velem = GetVElement(myBuffer, 0); if (velem != null) { AddVElement((LiquidArray)currentObj, velem); currentState = 7; } else { NotifyError(); isSuccess = false; } } else { object velem = GetVElement(myBuffer, 0); if (velem != null) { AddVElement((LiquidElement)currentObj, lastestKey, velem); currentState = 7; } else { NotifyError(); isSuccess = false; } } myBuffer.Length = 0; //clear } } else { myBuffer.Append(c); } } break; case 3: { switch (c) { case '"': { myBuffer.Append('\"'); } break; case '\'': { myBuffer.Append('\''); } break; case '/': { myBuffer.Append('/'); } break; case '\\': { myBuffer.Append('\\'); } break; case 'b': { myBuffer.Append('\b'); } break; case 'f': { myBuffer.Append('\f'); } break; case 'r': { myBuffer.Append('\r'); } break; case 'n': { myBuffer.Append('\n'); } break; case 't': { myBuffer.Append('\t'); } break; case 'u': { //unicode char in hexa digit uint c_uint = ParseUnicode(sourceBuffer[i + 1], sourceBuffer[i + 2], sourceBuffer[i + 3], sourceBuffer[i + 4]); myBuffer.Append((char)c_uint); i += 4; } break; default: { NotifyError(); isSuccess = false; } break; } if (isSuccess) { currentState = 2; } else { break; } } break; case 4: { if (c == ':') { currentState = 5; isInKeyPart = false; } else if (char.IsWhiteSpace(c)) { continue; } else { NotifyError(); isSuccess = false; break; } } break; case 5: { if (c == '"' || c == '\'') { openStringWithChar = c; currentState = 2; } else if (char.IsDigit(c) || c == '-') { myBuffer.Append(c); currentState = 8; } else if (c == '{') { myVElemStack.Push(currentObj); if (currentObj is LiquidElement) { myKeyStack.Push(lastestKey); } currentObj = doc.CreateElement("!j"); currentState = 1; isInKeyPart = true; } else if (c == '[') { myVElemStack.Push(currentObj); if (currentObj is LiquidElement) { myKeyStack.Push(lastestKey); } currentObj = new LqArray(); currentState = 5; isInKeyPart = false; } else if (c == ']') { if (currentObj is LiquidArray) { if (myVElemStack.Count > 0) { object velem = myVElemStack.Pop(); if (velem is LiquidElement) { lastestKey = myKeyStack.Pop(); AddVElement((LiquidElement)velem, lastestKey, currentObj); currentObj = velem; currentState = 7; } else { AddVElement((LiquidArray)velem, currentObj); currentObj = velem; } } } else { NotifyError(); isSuccess = false; } } else if (char.IsWhiteSpace(c)) { continue; } else if (c == 'n' || c == 't' || c == 'f') { currentState = 6; myBuffer.Append(c); } else { NotifyError(); isSuccess = false; break; } } break; case 6: { if (char.IsLetter(c)) { myBuffer.Append(c); } else if (c == ']' || c == '}' || c == ',') { if (myBuffer.Length > 0) { if (!EvaluateElement(currentObj, myBuffer, 3, c, lastestKey)) { NotifyError(); isSuccess = false; break; } } if (c == ']') { if (myVElemStack.Count > 0) { currentObj = myVElemStack.Pop(); } } else if (c == '}') { if (myVElemStack.Count > 0) { currentObj = myVElemStack.Pop(); lastestKey = myKeyStack.Pop(); } } else { if (currentObj is LiquidElement) { currentState = 1; isInKeyPart = true; } else if (currentObj is LiquidArray) { currentState = 5; } } } else { NotifyError(); isSuccess = false; } } break; case 7: { if (c == ',') { if (currentObj is LiquidElement) { currentState = 1; isInKeyPart = true; } else { currentState = 5; } } else if (c == ']') { if (myVElemStack.Count > 0) { object velem = myVElemStack.Pop(); if (velem is LiquidElement) { lastestKey = myKeyStack.Pop(); AddVElement((LiquidElement)velem, lastestKey, currentObj); currentObj = velem; } else { AddVElement((LiquidArray)velem, currentObj); currentObj = velem; } } } else if (c == '}') { if (myVElemStack.Count > 0) { object velem = myVElemStack.Pop(); if (velem is LiquidElement) { lastestKey = myKeyStack.Pop(); AddVElement((LiquidElement)velem, lastestKey, currentObj); currentObj = velem; } else { AddVElement((LiquidArray)velem, currentObj); currentObj = velem; } } } else if (c == '\r' || c == '\n') { //WARNING: review implivit comma implicitComma = true; } else { //WARNING: review implivit comma if (char.IsLetter(c) || c == '_' || c == '"') { if (implicitComma) { if (currentObj is LiquidElement) { currentState = 1; isInKeyPart = true; } else { currentState = 5; } i--; implicitComma = false; } } } } break; case 8: { if (char.IsDigit(c)) { myBuffer.Append(c); } else if (c == '.') { if (!isDoubleNumber) { myBuffer.Append(c); isDoubleNumber = true; } else { NotifyError(); isSuccess = false; break; } } else if (c == ']' || c == '}' || c == ',') { int suggestedType = 1; if (isDoubleNumber) { suggestedType = 2; isDoubleNumber = false; } if (myBuffer.Length > 0) { if (!EvaluateElement(currentObj, myBuffer, suggestedType, c, lastestKey)) { NotifyError(); isSuccess = false; break; } } if (c == ']') { if (myVElemStack.Count > 0) { object velem = myVElemStack.Pop(); if (velem is LiquidElement) { lastestKey = myKeyStack.Pop(); AddVElement((LiquidElement)velem, lastestKey, currentObj); currentObj = velem; } else { AddVElement((LiquidArray)velem, currentObj); currentObj = velem; } } } else if (c == '}') { if (myVElemStack.Count > 0) { object velem = myVElemStack.Pop(); if (velem is LiquidElement) { lastestKey = myKeyStack.Pop(); AddVElement((LiquidElement)velem, lastestKey, currentObj); currentObj = velem; } else { AddVElement((LiquidArray)velem, currentObj); currentObj = velem; } } } else { if (currentObj is LiquidElement) { currentState = 1; isInKeyPart = true; } else if (currentObj is LiquidArray) { currentState = 5; } } } else { NotifyError(); isSuccess = false; } } break; case 9: { if (char.IsLetter(c) || c == '_') { myBuffer.Append(c); } else if (c == ':') { if (isInKeyPart) { lastestKey = myBuffer.ToString(); myBuffer.Length = 0; //clear currentState = 5; isInKeyPart = false; } else { NotifyError(); isSuccess = false; } } else if (char.IsWhiteSpace(c)) { currentState = 4; } else { NotifyError(); isSuccess = false; } } break; } } //======================================= #if DEBUG //if (dbug_EnableLogParser) //{ // dbugDataFormatParser.End(); //} #endif //======================================= if (currentObj is LiquidElement && isSuccess) { //WARNNIG: reformat is our extension if (reformat) { ReFormatLqElement((LiquidElement)currentObj); } return((LiquidElement)currentObj); } else { return(null); } }