Skip to content

Commit a1c815d

Browse files
committed
Add Luaon.Json project.
Add JsonLuaWriter.
1 parent e71f78e commit a1c815d

File tree

6 files changed

+516
-20
lines changed

6 files changed

+516
-20
lines changed

Luaon.Json/JsonLuaWriter.cs

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.IO;
4+
using Newtonsoft.Json;
5+
6+
namespace Luaon.Json
7+
{
8+
/// <summary>
9+
/// A writer that accepts JSON tokens but outputs Lua table expression.
10+
/// </summary>
11+
public class JsonLuaWriter : JsonWriter
12+
{
13+
14+
private readonly TextWriter writer;
15+
private int _MaxUnquotedNameLength = 64;
16+
private int _Indentation = 2;
17+
private char _IndentChar;
18+
private int nestedLevel = 0;
19+
private char[] currentIdentation;
20+
private string currentIdentationNewLine;
21+
22+
public JsonLuaWriter(TextWriter writer)
23+
{
24+
this.writer = writer ?? throw new ArgumentNullException(nameof(writer));
25+
_Indentation = 2;
26+
_IndentChar = ' ';
27+
}
28+
29+
/// <summary>
30+
/// Gets/sets the maximum allowed table field name that will be checked for chance of
31+
/// using <c>Name = </c> expression instad of <c>["key"] = </c>, to reduce the
32+
/// generated code length and improve redability.
33+
/// </summary>
34+
/// <value>A positive value, or <c>0</c> to disable this feature.</value>
35+
/// <remarks>The default value is <c>64</c>.</remarks>
36+
public int MaxUnquotedNameLength
37+
{
38+
get { return _MaxUnquotedNameLength; }
39+
set
40+
{
41+
if (value < 0) throw new ArgumentOutOfRangeException(nameof(value));
42+
_MaxUnquotedNameLength = value;
43+
}
44+
}
45+
46+
/// <summary>
47+
/// Gets or sets how many <see cref="IndentChar"/>s to write for each level in the hierarchy
48+
/// when <see cref="Formatting"/> is set to <see cref="Formatting.Prettified"/>.
49+
/// </summary>
50+
public int Indentation
51+
{
52+
get { return _Indentation; }
53+
set
54+
{
55+
if (value < 0) throw new ArgumentOutOfRangeException(nameof(value));
56+
if (_Indentation != value)
57+
{
58+
_Indentation = value;
59+
currentIdentation = null;
60+
}
61+
}
62+
}
63+
64+
/// <summary>
65+
/// Gets/sets which character to use for indenting
66+
/// when <see cref="Formatting"/> is set to <see cref="Formatting.Prettified"/>.
67+
/// </summary>
68+
public char IndentChar
69+
{
70+
get { return _IndentChar; }
71+
set
72+
{
73+
if (_Indentation != value)
74+
{
75+
_IndentChar = value;
76+
currentIdentation = null;
77+
}
78+
}
79+
}
80+
81+
/// <inheritdoc />
82+
public override void WriteStartArray()
83+
{
84+
base.WriteStartArray();
85+
nestedLevel++;
86+
writer.Write('{');
87+
}
88+
89+
/// <inheritdoc />
90+
public override void WriteEndArray()
91+
{
92+
nestedLevel--;
93+
Debug.Assert(nestedLevel >= 0);
94+
base.WriteEndArray();
95+
}
96+
97+
/// <inheritdoc />
98+
public override void WriteStartObject()
99+
{
100+
base.WriteStartObject();
101+
nestedLevel++;
102+
writer.Write('{');
103+
}
104+
105+
/// <inheritdoc />
106+
public override void WriteEndObject()
107+
{
108+
nestedLevel--;
109+
Debug.Assert(nestedLevel >= 0);
110+
base.WriteEndObject();
111+
}
112+
113+
/// <inheritdoc />
114+
public override void WriteStartConstructor(string name)
115+
{
116+
throw new NotSupportedException();
117+
//base.WriteStartConstructor(name);
118+
}
119+
120+
/// <inheritdoc />
121+
public override void WriteEndConstructor()
122+
{
123+
throw new NotSupportedException();
124+
//base.WriteEndConstructor();
125+
}
126+
127+
/// <inheritdoc />
128+
protected override void WriteEnd(JsonToken token)
129+
{
130+
switch (token)
131+
{
132+
case JsonToken.EndObject:
133+
case JsonToken.EndArray:
134+
writer.Write('}');
135+
break;
136+
default:
137+
throw new NotSupportedException();
138+
}
139+
}
140+
141+
/// <inheritdoc />
142+
public override void WritePropertyName(string name)
143+
{
144+
base.WritePropertyName(name);
145+
if (name.Length > 0 && name.Length < _MaxUnquotedNameLength && LuaConvert.IsValidIdentifier(name))
146+
{
147+
writer.Write(name);
148+
}
149+
else
150+
{
151+
writer.Write('[');
152+
writer.Write(LuaConvert.ToString(name));
153+
writer.Write(']');
154+
}
155+
156+
if (Formatting == Newtonsoft.Json.Formatting.Indented)
157+
writer.Write(" ="); // base class will insert a space after =
158+
else
159+
writer.Write('=');
160+
}
161+
162+
/// <inheritdoc />
163+
protected override void WriteIndent()
164+
{
165+
var indentCount = nestedLevel * Indentation;
166+
if (currentIdentation == null || currentIdentation.Length - currentIdentationNewLine.Length < indentCount)
167+
{
168+
var newLine = writer.NewLine;
169+
var chars = new char[newLine.Length + indentCount];
170+
newLine.CopyTo(0, chars, 0, newLine.Length);
171+
for (int i = newLine.Length; i < chars.Length; i++) chars[i] = _IndentChar;
172+
currentIdentation = chars;
173+
currentIdentationNewLine = newLine;
174+
}
175+
176+
writer.Write(currentIdentation, 0, currentIdentationNewLine.Length + indentCount);
177+
}
178+
179+
/// <inheritdoc />
180+
protected override void WriteValueDelimiter()
181+
{
182+
writer.Write(',');
183+
}
184+
185+
/// <inheritdoc />
186+
protected override void WriteIndentSpace()
187+
{
188+
writer.Write(' ');
189+
}
190+
191+
#region WriteValue methods
192+
193+
/// <inheritdoc />
194+
public override void WriteNull()
195+
{
196+
base.WriteNull();
197+
writer.Write(LuaConvert.Nil);
198+
}
199+
200+
public override void WriteUndefined()
201+
{
202+
throw new NotSupportedException();
203+
//base.WriteUndefined();
204+
}
205+
206+
/// <inheritdoc />
207+
public override void WriteRaw(string json)
208+
{
209+
// Actually, this should be Lua
210+
base.WriteRaw(json);
211+
writer.Write(json);
212+
}
213+
214+
/// <inheritdoc />
215+
public override void WriteValue(string value)
216+
{
217+
base.WriteValue(value);
218+
if (value == null)
219+
writer.Write(LuaConvert.Nil);
220+
else
221+
writer.Write(LuaConvert.ToString(value));
222+
}
223+
224+
/// <inheritdoc />
225+
public override void WriteValue(bool value)
226+
{
227+
base.WriteValue(value);
228+
writer.Write(LuaConvert.ToString(value));
229+
}
230+
231+
/// <inheritdoc />
232+
public override void WriteValue(char value)
233+
{
234+
base.WriteValue(value);
235+
writer.Write(LuaConvert.ToString(value));
236+
}
237+
238+
/// <inheritdoc />
239+
public override void WriteValue(byte value)
240+
{
241+
base.WriteValue(value);
242+
writer.Write(LuaConvert.ToString(value));
243+
}
244+
245+
/// <inheritdoc />
246+
public override void WriteValue(sbyte value)
247+
{
248+
base.WriteValue(value);
249+
writer.Write(LuaConvert.ToString(value));
250+
}
251+
252+
/// <inheritdoc />
253+
public override void WriteValue(short value)
254+
{
255+
base.WriteValue(value);
256+
writer.Write(LuaConvert.ToString(value));
257+
}
258+
259+
/// <inheritdoc />
260+
public override void WriteValue(ushort value)
261+
{
262+
base.WriteValue(value);
263+
writer.Write(LuaConvert.ToString(value));
264+
}
265+
266+
/// <inheritdoc />
267+
public override void WriteValue(int value)
268+
{
269+
base.WriteValue(value);
270+
writer.Write(LuaConvert.ToString(value));
271+
}
272+
273+
/// <inheritdoc />
274+
public override void WriteValue(uint value)
275+
{
276+
base.WriteValue(value);
277+
writer.Write(LuaConvert.ToString(value));
278+
}
279+
280+
/// <inheritdoc />
281+
public override void WriteValue(long value)
282+
{
283+
base.WriteValue(value);
284+
writer.Write(LuaConvert.ToString(value));
285+
}
286+
287+
/// <inheritdoc />
288+
public override void WriteValue(ulong value)
289+
{
290+
base.WriteValue(value);
291+
writer.Write(LuaConvert.ToString(value));
292+
}
293+
294+
/// <inheritdoc />
295+
public override void WriteValue(float value)
296+
{
297+
base.WriteValue(value);
298+
writer.Write(LuaConvert.ToString(value));
299+
}
300+
301+
/// <inheritdoc />
302+
public override void WriteValue(double value)
303+
{
304+
base.WriteValue(value);
305+
writer.Write(LuaConvert.ToString(value));
306+
}
307+
308+
/// <inheritdoc />
309+
public override void WriteValue(decimal value)
310+
{
311+
base.WriteValue(value);
312+
writer.Write(LuaConvert.ToString(value));
313+
}
314+
315+
/// <inheritdoc />
316+
public override void WriteValue(DateTime value)
317+
{
318+
base.WriteValue(value);
319+
writer.Write(LuaConvert.ToString(value));
320+
}
321+
322+
/// <inheritdoc />
323+
public override void WriteValue(DateTimeOffset value)
324+
{
325+
base.WriteValue(value);
326+
writer.Write(LuaConvert.ToString(value));
327+
}
328+
329+
/// <inheritdoc />
330+
public override void WriteValue(byte[] value)
331+
{
332+
base.WriteValue(value);
333+
writer.Write('"');
334+
writer.Write(Convert.ToBase64String(value));
335+
writer.Write('"');
336+
}
337+
338+
/// <inheritdoc />
339+
public override void WriteValue(Guid value)
340+
{
341+
base.WriteValue(value);
342+
writer.Write(LuaConvert.ToString(value.ToString("D")));
343+
}
344+
345+
/// <inheritdoc />
346+
public override void WriteValue(TimeSpan value)
347+
{
348+
base.WriteValue(value);
349+
writer.Write(LuaConvert.ToString(value));
350+
}
351+
352+
/// <inheritdoc />
353+
public override void WriteValue(Uri value)
354+
{
355+
base.WriteValue(value);
356+
if (value == null)
357+
writer.Write(LuaConvert.Nil);
358+
else
359+
writer.Write(LuaConvert.ToString(value));
360+
}
361+
362+
#endregion
363+
364+
/// <inheritdoc />
365+
public override void Flush()
366+
{
367+
writer.Flush();
368+
}
369+
370+
/// <inheritdoc />
371+
protected override void Dispose(bool disposing)
372+
{
373+
if (disposing)
374+
{
375+
if (CloseOutput) writer.Dispose();
376+
}
377+
base.Dispose(disposing);
378+
}
379+
}
380+
}

Luaon.Json/Luaon.Json.csproj

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard1.1;netstandard2.0</TargetFrameworks>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
9+
</ItemGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\Luaon.NET\Luaon.NET.csproj" />
13+
</ItemGroup>
14+
15+
</Project>

0 commit comments

Comments
 (0)