606 lines
19 KiB
C#
606 lines
19 KiB
C#
|
#region MigraDoc - Creating Documents on the Fly
|
|||
|
//
|
|||
|
// Authors:
|
|||
|
// Stefan Lange
|
|||
|
// Klaus Potzesny
|
|||
|
// David Stephensen
|
|||
|
//
|
|||
|
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
|
|||
|
//
|
|||
|
// http://www.pdfsharp.com
|
|||
|
// http://www.migradoc.com
|
|||
|
// http://sourceforge.net/projects/pdfsharp
|
|||
|
//
|
|||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
|
// copy of this software and associated documentation files (the "Software"),
|
|||
|
// to deal in the Software without restriction, including without limitation
|
|||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|||
|
// Software is furnished to do so, subject to the following conditions:
|
|||
|
//
|
|||
|
// The above copyright notice and this permission notice shall be included
|
|||
|
// in all copies or substantial portions of the Software.
|
|||
|
//
|
|||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|||
|
// DEALINGS IN THE SOFTWARE.
|
|||
|
#endregion
|
|||
|
|
|||
|
using System;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.Globalization;
|
|||
|
using System.IO;
|
|||
|
using System.Text;
|
|||
|
using MigraDoc.DocumentObjectModel.publics;
|
|||
|
|
|||
|
namespace MigraDoc.DocumentObjectModel
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Object to be passed to the Serialize function of a DocumentObject to convert
|
|||
|
/// it into DDL.
|
|||
|
/// </summary>
|
|||
|
public sealed class Serializer
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// A Serializer object for converting MDDOM into DDL.
|
|||
|
/// </summary>
|
|||
|
/// <param name="textWriter">A TextWriter to write DDL in.</param>
|
|||
|
/// <param name="indent">Indent of a new block. Default is 2.</param>
|
|||
|
/// <param name="initialIndent">Initial indent to start with.</param>
|
|||
|
public Serializer(TextWriter textWriter, int indent, int initialIndent)
|
|||
|
{
|
|||
|
if (textWriter == null)
|
|||
|
throw new ArgumentNullException("textWriter");
|
|||
|
|
|||
|
_textWriter = textWriter;
|
|||
|
_indent = indent;
|
|||
|
_writeIndent = initialIndent;
|
|||
|
if (textWriter is StreamWriter)
|
|||
|
WriteStamp();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initializes a new instance of the Serializer class with the specified TextWriter.
|
|||
|
/// </summary>
|
|||
|
public Serializer(TextWriter textWriter) : this(textWriter, 2, 0) { }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initializes a new instance of the Serializer class with the specified TextWriter and indentation.
|
|||
|
/// </summary>
|
|||
|
public Serializer(TextWriter textWriter, int indent) : this(textWriter, indent, 0) { }
|
|||
|
|
|||
|
readonly TextWriter _textWriter;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets or sets the indentation for a new indentation level.
|
|||
|
/// </summary>
|
|||
|
public int Indent
|
|||
|
{
|
|||
|
get { return _indent; }
|
|||
|
set { _indent = value; }
|
|||
|
}
|
|||
|
int _indent = 2;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets or sets the initial indentation which precede every line.
|
|||
|
/// </summary>
|
|||
|
public int InitialIndent
|
|||
|
{
|
|||
|
get { return _writeIndent; }
|
|||
|
set { _writeIndent = value; }
|
|||
|
}
|
|||
|
int _writeIndent;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Increases indent of DDL code.
|
|||
|
/// </summary>
|
|||
|
void IncreaseIndent()
|
|||
|
{
|
|||
|
_writeIndent += _indent;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Decreases indent of DDL code.
|
|||
|
/// </summary>
|
|||
|
void DecreaseIndent()
|
|||
|
{
|
|||
|
_writeIndent -= _indent;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Writes the header for a DDL file containing copyright and creation time information.
|
|||
|
/// </summary>
|
|||
|
public void WriteStamp()
|
|||
|
{
|
|||
|
if (_fWriteStamp)
|
|||
|
{
|
|||
|
WriteComment("Created by empira MigraDoc Document Object Model");
|
|||
|
WriteComment(String.Format("generated file created {0:d} at {0:t}", DateTime.Now));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Appends a string indented without line feed.
|
|||
|
/// </summary>
|
|||
|
public void Write(string str)
|
|||
|
{
|
|||
|
string wrappedStr = DoWordWrap(str);
|
|||
|
if (wrappedStr.Length < str.Length && wrappedStr != "")
|
|||
|
{
|
|||
|
WriteLineToStream(wrappedStr);
|
|||
|
Write(str.Substring(wrappedStr.Length));
|
|||
|
}
|
|||
|
else
|
|||
|
WriteToStream(str);
|
|||
|
CommitText();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Writes a string indented with line feed.
|
|||
|
/// </summary>
|
|||
|
public void WriteLine(string str)
|
|||
|
{
|
|||
|
string wrappedStr = DoWordWrap(str);
|
|||
|
if (wrappedStr.Length < str.Length)
|
|||
|
{
|
|||
|
WriteLineToStream(wrappedStr);
|
|||
|
WriteLine(str.Substring(wrappedStr.Length));
|
|||
|
}
|
|||
|
else
|
|||
|
WriteLineToStream(wrappedStr);
|
|||
|
CommitText();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns the part of the string str that fits into the line (up to 80 chars).
|
|||
|
/// If Wordwrap is impossible it returns the input-string str itself.
|
|||
|
/// </summary>
|
|||
|
string DoWordWrap(string str)
|
|||
|
{
|
|||
|
if (str.Length + _writeIndent < LineBreakBeyond)
|
|||
|
return str;
|
|||
|
|
|||
|
int idxCRLF = str.IndexOf("\x0D\x0A", StringComparison.Ordinal);
|
|||
|
if (idxCRLF > 0 && idxCRLF + _writeIndent <= LineBreakBeyond)
|
|||
|
return str.Substring(0, idxCRLF + 1);
|
|||
|
|
|||
|
int splitIndexBlank = str.Substring(0, LineBreakBeyond - _writeIndent).LastIndexOf(" ", StringComparison.Ordinal);
|
|||
|
int splitIndexCRLF = str.Substring(0, LineBreakBeyond - _writeIndent).LastIndexOf("\x0D\x0A", StringComparison.Ordinal);
|
|||
|
int splitIndex = Math.Max(splitIndexBlank, splitIndexCRLF);
|
|||
|
if (splitIndex == -1)
|
|||
|
splitIndex = Math.Min(str.IndexOf(" ", LineBreakBeyond - _writeIndent + 1, StringComparison.Ordinal),
|
|||
|
str.IndexOf("\x0D\x0A", LineBreakBeyond - _writeIndent + 1, StringComparison.Ordinal));
|
|||
|
return splitIndex > 0 ? str.Substring(0, splitIndex) : str;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Writes an empty line.
|
|||
|
/// </summary>
|
|||
|
public void WriteLine()
|
|||
|
{
|
|||
|
WriteLine(String.Empty);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Write a line without committing (without marking the text as serialized).
|
|||
|
/// </summary>
|
|||
|
public void WriteLineNoCommit(string str)
|
|||
|
{
|
|||
|
WriteLineToStream(str);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Write a line without committing (without marking the text as serialized).
|
|||
|
/// </summary>
|
|||
|
public void WriteLineNoCommit()
|
|||
|
{
|
|||
|
WriteLineNoCommit(String.Empty);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Writes a text as comment and automatically word-wraps it.
|
|||
|
/// </summary>
|
|||
|
public void WriteComment(string comment)
|
|||
|
{
|
|||
|
if (String.IsNullOrEmpty(comment))
|
|||
|
return;
|
|||
|
|
|||
|
// if string contains CR/LF, split up recursively
|
|||
|
int crlf = comment.IndexOf("\x0D\x0A", StringComparison.Ordinal);
|
|||
|
if (crlf != -1)
|
|||
|
{
|
|||
|
WriteComment(comment.Substring(0, crlf));
|
|||
|
WriteComment(comment.Substring(crlf + 2));
|
|||
|
return;
|
|||
|
}
|
|||
|
CloseUpLine();
|
|||
|
int len;
|
|||
|
int chopBeyond = LineBreakBeyond - _indent - "// ".Length;
|
|||
|
while ((len = comment.Length) > 0)
|
|||
|
{
|
|||
|
string wrt;
|
|||
|
if (len <= chopBeyond)
|
|||
|
{
|
|||
|
wrt = "// " + comment;
|
|||
|
comment = String.Empty;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
int idxChop;
|
|||
|
if ((idxChop = comment.LastIndexOf(' ', chopBeyond)) == -1 &&
|
|||
|
(idxChop = comment.IndexOf(' ', chopBeyond)) == -1)
|
|||
|
{
|
|||
|
wrt = "// " + comment;
|
|||
|
comment = String.Empty;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
wrt = "// " + comment.Substring(0, idxChop);
|
|||
|
comment = comment.Substring(idxChop + 1);
|
|||
|
}
|
|||
|
}
|
|||
|
WriteLineToStream(wrt);
|
|||
|
CommitText();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Writes a line break if the current position is not at the beginning
|
|||
|
/// of a new line.
|
|||
|
/// </summary>
|
|||
|
public void CloseUpLine()
|
|||
|
{
|
|||
|
if (_linePos > 0)
|
|||
|
WriteLine();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Effectively writes text to the stream. The text is automatically indented and
|
|||
|
/// word-wrapped. A given text gets never word-wrapped to keep comments or string
|
|||
|
/// literals unbroken.
|
|||
|
/// </summary>
|
|||
|
void WriteToStream(string text, bool fLineBreak, bool fAutoIndent)
|
|||
|
{
|
|||
|
// if string contains CR/LF, split up recursively
|
|||
|
int crlf = text.IndexOf("\x0D\x0A", StringComparison.Ordinal);
|
|||
|
if (crlf != -1)
|
|||
|
{
|
|||
|
WriteToStream(text.Substring(0, crlf), true, fAutoIndent);
|
|||
|
WriteToStream(text.Substring(crlf + 2), fLineBreak, fAutoIndent);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
int len = text.Length;
|
|||
|
if (len > 0)
|
|||
|
{
|
|||
|
if (_linePos > 0)
|
|||
|
{
|
|||
|
// does not work
|
|||
|
// if (IsBlankRequired(this .lastChar, _text[0]))
|
|||
|
// _text = "<22>" + _text;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (fAutoIndent)
|
|||
|
{
|
|||
|
text = Indentation + text;
|
|||
|
len += _writeIndent;
|
|||
|
}
|
|||
|
}
|
|||
|
_textWriter.Write(text);
|
|||
|
_linePos += len;
|
|||
|
// wordwrap required?
|
|||
|
if (_linePos > LineBreakBeyond)
|
|||
|
{
|
|||
|
fLineBreak = true;
|
|||
|
//this .textWriter.Write("//<2F>"); // for debugging only
|
|||
|
}
|
|||
|
else
|
|||
|
_lastChar = text[len - 1];
|
|||
|
}
|
|||
|
|
|||
|
if (fLineBreak)
|
|||
|
{
|
|||
|
_textWriter.WriteLine(String.Empty); // what a line break is may depend on encoding
|
|||
|
_linePos = 0;
|
|||
|
_lastChar = '\x0A';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Write the text into the stream without breaking it and adds an indentation to it.
|
|||
|
/// </summary>
|
|||
|
void WriteToStream(string text)
|
|||
|
{
|
|||
|
WriteToStream(text, false, true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Write a line to the stream.
|
|||
|
/// </summary>
|
|||
|
void WriteLineToStream(string text)
|
|||
|
{
|
|||
|
WriteToStream(text, true, true);
|
|||
|
}
|
|||
|
|
|||
|
///// <summary>
|
|||
|
///// Mighty function to figure out if a blank is required as separator.
|
|||
|
///// // Does not work without context...
|
|||
|
///// </summary>
|
|||
|
//bool IsBlankRequired(char left, char right)
|
|||
|
//{
|
|||
|
// if (left == ' ' || right == ' ')
|
|||
|
// return false;
|
|||
|
|
|||
|
// // 1st try
|
|||
|
// bool leftLetterOrDigit = Char.IsLetterOrDigit(left);
|
|||
|
// bool rightLetterOrDigit = Char.IsLetterOrDigit(right);
|
|||
|
|
|||
|
// if (leftLetterOrDigit && rightLetterOrDigit)
|
|||
|
// return true;
|
|||
|
|
|||
|
// return false;
|
|||
|
//}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Start attribute part.
|
|||
|
/// </summary>
|
|||
|
public int BeginAttributes()
|
|||
|
{
|
|||
|
int pos = Position;
|
|||
|
WriteLineNoCommit("[");
|
|||
|
IncreaseIndent();
|
|||
|
BeginBlock();
|
|||
|
return pos;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Start attribute part.
|
|||
|
/// </summary>
|
|||
|
public int BeginAttributes(string str)
|
|||
|
{
|
|||
|
int pos = Position;
|
|||
|
WriteLineNoCommit(str);
|
|||
|
WriteLineNoCommit("[");
|
|||
|
IncreaseIndent();
|
|||
|
BeginBlock();
|
|||
|
return pos;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// End attribute part.
|
|||
|
/// </summary>
|
|||
|
public bool EndAttributes()
|
|||
|
{
|
|||
|
DecreaseIndent();
|
|||
|
WriteLineNoCommit("]");
|
|||
|
return EndBlock();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// End attribute part.
|
|||
|
/// </summary>
|
|||
|
public bool EndAttributes(int pos)
|
|||
|
{
|
|||
|
bool commit = EndAttributes();
|
|||
|
if (!commit)
|
|||
|
Position = pos;
|
|||
|
return commit;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Write attribute of type Unit, Color, int, float, double, bool, string or enum.
|
|||
|
/// </summary>
|
|||
|
public void WriteSimpleAttribute(string valueName, object value)
|
|||
|
{
|
|||
|
INullableValue ival = value as INullableValue;
|
|||
|
if (ival != null)
|
|||
|
value = ival.GetValue();
|
|||
|
|
|||
|
Type type = value.GetType();
|
|||
|
|
|||
|
if (type == typeof(Unit))
|
|||
|
{
|
|||
|
string strUnit = value.ToString();
|
|||
|
if (((Unit)value).Type == UnitType.Point)
|
|||
|
WriteLine(valueName + " = " + strUnit);
|
|||
|
else
|
|||
|
WriteLine(valueName + " = \"" + strUnit + "\"");
|
|||
|
}
|
|||
|
else if (type == typeof(float))
|
|||
|
{
|
|||
|
WriteLine(valueName + " = " + ((float)value).ToString(CultureInfo.InvariantCulture));
|
|||
|
}
|
|||
|
else if (type == typeof(double))
|
|||
|
{
|
|||
|
WriteLine(valueName + " = " + ((double)value).ToString(CultureInfo.InvariantCulture));
|
|||
|
}
|
|||
|
else if (type == typeof(bool))
|
|||
|
{
|
|||
|
WriteLine(valueName + " = " + value.ToString().ToLower());
|
|||
|
}
|
|||
|
else if (type == typeof(string))
|
|||
|
{
|
|||
|
StringBuilder sb = new StringBuilder(value.ToString());
|
|||
|
sb.Replace("\\", "\\\\");
|
|||
|
sb.Replace("\"", "\\\"");
|
|||
|
WriteLine(valueName + " = \"" + sb + "\"");
|
|||
|
}
|
|||
|
#if !NETFX_CORE
|
|||
|
else if (type == typeof(int) || type.BaseType == typeof(Enum) || type == typeof(Color))
|
|||
|
#else
|
|||
|
else if (type == typeof(int) || type.GetTypeInfo().BaseType == typeof(Enum) || type == typeof(Color))
|
|||
|
#endif
|
|||
|
{
|
|||
|
WriteLine(valueName + " = " + value);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
string message = String.Format("Type '{0}' of value '{1}' not supported", type, valueName);
|
|||
|
Debug.Assert(false, message);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Start content part.
|
|||
|
/// </summary>
|
|||
|
public int BeginContent()
|
|||
|
{
|
|||
|
int pos = Position;
|
|||
|
WriteLineNoCommit("{");
|
|||
|
IncreaseIndent();
|
|||
|
BeginBlock();
|
|||
|
return pos;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Start content part.
|
|||
|
/// </summary>
|
|||
|
public int BeginContent(string str)
|
|||
|
{
|
|||
|
int pos = Position;
|
|||
|
WriteLineNoCommit(str);
|
|||
|
WriteLineNoCommit("{");
|
|||
|
IncreaseIndent();
|
|||
|
BeginBlock();
|
|||
|
return pos;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// End content part.
|
|||
|
/// </summary>
|
|||
|
public bool EndContent()
|
|||
|
{
|
|||
|
DecreaseIndent();
|
|||
|
WriteLineNoCommit("}");
|
|||
|
return EndBlock();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// End content part.
|
|||
|
/// </summary>
|
|||
|
public bool EndContent(int pos)
|
|||
|
{
|
|||
|
bool commit = EndContent();
|
|||
|
if (!commit)
|
|||
|
Position = pos;
|
|||
|
return commit;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Starts a new nesting block.
|
|||
|
/// </summary>
|
|||
|
public int BeginBlock()
|
|||
|
{
|
|||
|
int pos = Position;
|
|||
|
if (_stackIdx + 1 >= _commitTextStack.Length)
|
|||
|
throw new ArgumentException("Block nesting level exhausted.");
|
|||
|
_stackIdx += 1;
|
|||
|
_commitTextStack[_stackIdx] = false;
|
|||
|
return pos;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Ends a nesting block.
|
|||
|
/// </summary>
|
|||
|
public bool EndBlock()
|
|||
|
{
|
|||
|
if (_stackIdx <= 0)
|
|||
|
throw new ArgumentException("Block nesting level underflow.");
|
|||
|
_stackIdx -= 1;
|
|||
|
if (_commitTextStack[_stackIdx + 1])
|
|||
|
_commitTextStack[_stackIdx] = _commitTextStack[_stackIdx + 1];
|
|||
|
return _commitTextStack[_stackIdx + 1];
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Ends a nesting block.
|
|||
|
/// </summary>
|
|||
|
public bool EndBlock(int pos)
|
|||
|
{
|
|||
|
bool commit = EndBlock();
|
|||
|
if (!commit)
|
|||
|
Position = pos;
|
|||
|
return commit;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets or sets the position within the underlying stream.
|
|||
|
/// </summary>
|
|||
|
int Position
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
_textWriter.Flush();
|
|||
|
StreamWriter streamWriter = _textWriter as StreamWriter;
|
|||
|
if (streamWriter != null)
|
|||
|
return (int)streamWriter.BaseStream.Position;
|
|||
|
|
|||
|
StringWriter stringWriter = _textWriter as StringWriter;
|
|||
|
if (stringWriter != null)
|
|||
|
return stringWriter.GetStringBuilder().Length;
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
set
|
|||
|
{
|
|||
|
_textWriter.Flush();
|
|||
|
StreamWriter streamWriter = _textWriter as StreamWriter;
|
|||
|
if (streamWriter != null)
|
|||
|
streamWriter.BaseStream.SetLength(value);
|
|||
|
else
|
|||
|
{
|
|||
|
StringWriter stringWriter = _textWriter as StringWriter;
|
|||
|
if (stringWriter != null)
|
|||
|
stringWriter.GetStringBuilder().Length = value;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Flushes the buffers of the underlying text writer.
|
|||
|
/// </summary>
|
|||
|
public void Flush()
|
|||
|
{
|
|||
|
_textWriter.Flush();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns an indent string of blanks.
|
|||
|
/// </summary>
|
|||
|
static string Ind(int indent)
|
|||
|
{
|
|||
|
return new String(' ', indent);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets an indent string of current indent.
|
|||
|
/// </summary>
|
|||
|
string Indentation
|
|||
|
{
|
|||
|
get { return Ind(_writeIndent); }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Marks the current block as 'committed'. That means the block contains
|
|||
|
/// serialized data.
|
|||
|
/// </summary>
|
|||
|
private void CommitText()
|
|||
|
{
|
|||
|
_commitTextStack[_stackIdx] = true;
|
|||
|
}
|
|||
|
int _stackIdx;
|
|||
|
readonly bool[] _commitTextStack = new bool[32];
|
|||
|
|
|||
|
int _linePos;
|
|||
|
const int LineBreakBeyond = 200;
|
|||
|
char _lastChar;
|
|||
|
bool _fWriteStamp = false;
|
|||
|
}
|
|||
|
}
|