using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using FastReport.Table;
using FastReport.Utils;
namespace FastReport.Export.Json
{
///
/// Represents the JSON export filter.
///
public partial class JsonExport : ExportBase
{
#region Fields
Encoding encoding;
int indent;
string indention = " ";
int pageNo = 0;
bool isCommaNeed = false;
#endregion
#region Private Methods
void write(Stream target, string data)
{
if (string.IsNullOrEmpty(data))
return;
if (data.StartsWith("{") && isCommaNeed)
{
var trailedBytes = encoding.GetBytes("," + Environment.NewLine);
long newPosition = target.Length - encoding.GetBytes(Environment.NewLine).Length;
if (newPosition >= 0)
{
target.Position = newPosition;
target.Write(trailedBytes, 0, trailedBytes.Length);
}
}
isCommaNeed = false;
if (data.EndsWith("}"))
isCommaNeed = true;
data = appendIndention(data);
byte[] bytes = encoding.GetBytes(data + Environment.NewLine);
target.Write(bytes, 0, bytes.Length);
}
string appendIndention(string str)
{
for (int i = 0; i < indent; i++)
str = indention + str;
return str;
}
string comma(int i, int length)
{
return i < length - 1 ? "," : "";
}
string wrap(string s)
{
if (string.IsNullOrEmpty(s))
return "\"\"";
char c = '\0';
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
string t;
for (i = 0; i < len; i += 1)
{
c = s[i];
switch (c)
{
case '\\':
case '"':
sb.Append('\\');
sb.Append(c);
break;
case '/':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
sb.Append("\\r");
break;
default:
if (c < ' ')
{
t = "000" + String.Format("X", c);
sb.Append("\\u" + t.Substring(t.Length - 4));
}
else
{
sb.Append(c);
}
break;
}
}
return "\"" + sb.ToString() + "\"";
}
void exportObj(Base c, List items)
{
if (c is ReportComponentBase && (c as ReportComponentBase).Exportable)
{
ReportComponentBase obj = c as ReportComponentBase;
//if (FDataOnly && (obj.Parent == null || !(obj.Parent is DataBand)))
//continue;
//if (obj is TableCell)
//continue;
if (obj is TextObject)
{
TextObject text = obj as TextObject;
if (!string.IsNullOrEmpty(text.Text))
items.Add("{\"TextObject\":" + wrap(text.Text) + "}");
}
else if (obj is PictureObject)
{
PictureObject pic = obj as PictureObject;
if (!string.IsNullOrEmpty(pic.ImageLocation))
items.Add("{\"PictureObject\":" + wrap(pic.ImageLocation) + "}");
}
else if (obj is RichObject)
{
RichObject rich = obj as RichObject;
if (!string.IsNullOrEmpty(rich.Text))
items.Add("{\"RichObject\":" + wrap(rich.Text) + "}");
}
else if (obj is HtmlObject)
{
HtmlObject html = obj as HtmlObject;
if (!string.IsNullOrEmpty(html.Text))
items.Add("{\"HtmlObject\":" + wrap(html.Text) + "}");
}
else if (obj is TableBase)
{
StringBuilder tableData = new StringBuilder();
tableData.Append("{\"TableObject\":[");
indent++;
TableBase table = obj as TableBase;
for (int i = 0; i < table.RowCount; i++)
{
string row = "[";
for (int j = 0; j < table.ColumnCount; j++)
{
TableCell cell = table[j, i];
row += wrap(cell.Text) + comma(j, table.ColumnCount);
}
row += "]" + comma(i, table.RowCount);
tableData.Append(Environment.NewLine + appendIndention(row));
}
indent--;
tableData.Append(Environment.NewLine + appendIndention("]}"));
items.Add(tableData.ToString());
}
}
}
#endregion
#region Protected Methods
///
protected override void Start()
{
base.Start();
pageNo = 0;
write(Stream, "{");
indent++;
write(Stream, "\"report\": [");
indent++;
}
///
protected override void Finish()
{
indent--;
write(Stream, "]");
indent--;
write(Stream, "}");
}
///
protected override string GetFileFilter()
{
return new MyRes("FileFilters").Get("JsonFile");
}
///
protected override void ExportPageBegin(ReportPage page)
{
base.ExportPageBegin(page);
write(Stream, "{");
indent++;
write(Stream, "\"page\":\"" + (pageNo + 1) + "\",");
write(Stream, "\"items\":[");
indent++;
}
///
protected override void ExportPageEnd(ReportPage page)
{
base.ExportPageEnd(page);
indent--;
write(Stream, "]");
indent--;
write(Stream, "}" + comma(pageNo, Pages.Length));
pageNo++;
}
///
protected override void ExportBand(BandBase band)
{
base.ExportBand(band);
List items = new List();
exportObj(band, items);
foreach (Base c in band.ForEachAllConvectedObjects(this))
exportObj(c, items);
for (int i = 0; i < items.Count; i++)
{
string item = items[i];
if (string.IsNullOrEmpty(item))
continue;
write(Stream, item + comma(i, items.Count));
}
}
#endregion
///
/// Initializes a new instance of the class.
///
public JsonExport()
{
encoding = Encoding.Unicode;
}
}
}