Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 55 additions & 22 deletions src/OneScript.StandardLibrary/Xml/XmlWriterImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public class XmlWriterImpl : AutoContext<XmlWriterImpl>, IDisposable
{
private TextWriterWithSettings _internalTextWriter;
private XmlTextWriter _writer;
private XmlWriterSettingsImpl _settings = (XmlWriterSettingsImpl)XmlWriterSettingsImpl.Constructor();
private XmlWriterSettingsImpl _settings = XmlWriterSettingsImpl.Constructor();
private int _depth;
private Stack<Dictionary<string, string>> _nsmap = new Stack<Dictionary<string, string>>();
private readonly Stack<Dictionary<string, string>> _nsmap = new();
private StringBuilder _stringBuffer;

private const string DEFAULT_INDENT_STRING = " ";
Expand All @@ -51,6 +51,12 @@ private void ExitScope()
--_depth;
}

private void CheckIfOpen()
{
if (_writer == null)
throw NotOpenException();
}

Comment thread
coderabbitai[bot] marked this conversation as resolved.
#region Properties

[ContextProperty("Отступ","Indent")]
Expand All @@ -77,8 +83,9 @@ public XmlWriterSettingsImpl Settings

[ContextMethod("ЗаписатьАтрибут","WriteAttribute")]
public void WriteAttribute(string localName, string valueOrNamespace, string value = null)
{
if(value == null)
{
CheckIfOpen();
if (value == null)
{
_writer.WriteAttributeString(localName, valueOrNamespace);
}
Expand All @@ -91,30 +98,35 @@ public void WriteAttribute(string localName, string valueOrNamespace, string val
[ContextMethod("ЗаписатьБезОбработки","WriteRaw")]
public void WriteRaw(string data)
{
CheckIfOpen();
_writer.WriteRaw(data);
}

[ContextMethod("ЗаписатьИнструкциюОбработки","WriteProcessingInstruction")]
public void WriteProcessingInstruction(string name, string text)
{
CheckIfOpen();
_writer.WriteProcessingInstruction(name, text);
}

[ContextMethod("ЗаписатьКомментарий","WriteComment")]
public void WriteComment(string text)
{
CheckIfOpen();
_writer.WriteComment(text);
}

[ContextMethod("ЗаписатьКонецАтрибута","WriteEndAttribute")]
public void WriteEndAttribute()
{
CheckIfOpen();
_writer.WriteEndAttribute();
}

[ContextMethod("ЗаписатьКонецЭлемента","WriteEndElement")]
public void WriteEndElement()
{
CheckIfOpen();
_internalTextWriter.TrimEndSlashes = true;
_writer.WriteEndElement();
_internalTextWriter.TrimEndSlashes = false;
Expand All @@ -124,7 +136,8 @@ public void WriteEndElement()
[ContextMethod("ЗаписатьНачалоАтрибута","WriteStartAttribute")]
public void WriteStartAttribute(string name, string ns = null)
{
if(ns == null)
CheckIfOpen();
if (ns == null)
{
_writer.WriteStartAttribute(name);
}
Expand All @@ -138,6 +151,7 @@ public void WriteStartAttribute(string name, string ns = null)
[ContextMethod("ЗаписатьНачалоЭлемента","WriteStartElement")]
public void WriteStartElement(string name, string ns = null)
{
CheckIfOpen();
if (ns == null)
{
_writer.WriteStartElement(name);
Expand All @@ -152,37 +166,43 @@ public void WriteStartElement(string name, string ns = null)
[ContextMethod("ЗаписатьОбъявлениеXML","WriteXMLDeclaration")]
public void WriteXMLDeclaration()
{
CheckIfOpen();
_writer.WriteStartDocument();
}

[ContextMethod("ЗаписатьСекциюCDATA","WriteCDATASection")]
public void WriteCDATASection(string data)
{
CheckIfOpen();
_writer.WriteCData(data);
}

[ContextMethod("ЗаписатьСоответствиеПространстваИмен","WriteNamespaceMapping")]
public void WriteNamespaceMapping(string prefix, string uri)
{
CheckIfOpen();
_writer.WriteAttributeString("xmlns", prefix, null, uri);
_nsmap.Peek()[prefix] = uri;
}

[ContextMethod("ЗаписатьСсылкуНаСущность","WriteEntityReference")]
public void WriteEntityReference(string name)
{
CheckIfOpen();
_writer.WriteEntityRef(name);
}

[ContextMethod("ЗаписатьТекст","WriteText")]
public void WriteText(string text)
{
CheckIfOpen();
_writer.WriteString(text);
}

[ContextMethod("ЗаписатьТекущий","WriteCurrent")]
public void WriteCurrent(XmlReaderImpl reader)
{
CheckIfOpen();
var nodeType = reader.NodeType.UnderlyingValue;
switch (nodeType)
{
Expand Down Expand Up @@ -225,7 +245,8 @@ public void WriteCurrent(XmlReaderImpl reader)
case XmlNodeType.Document:
case XmlNodeType.DocumentFragment:
case XmlNodeType.Notation:
throw new RuntimeException(new Localization.BilingualString($"Копирование узла {nodeType} не поддерживается"));
throw CopyingNotSupportedException(nodeType);

default:
break;
}
Expand Down Expand Up @@ -292,7 +313,8 @@ private static (string prefix, string localName) splitName(string nameOrLocalNam
[ContextMethod("ЗаписатьТипДокумента","WriteDocumentType")]
public void WriteDocumentType(string name, string varArg2, string varArg3 = null, string varArg4 = null)
{
if(varArg4 != null)
CheckIfOpen();
if (varArg4 != null)
{
_writer.WriteDocType(name, varArg2, varArg3, varArg4);
}
Expand All @@ -309,6 +331,7 @@ public void WriteDocumentType(string name, string varArg2, string varArg3 = null
[ContextMethod("НайтиПрефикс","LookupPrefix")]
public IValue LookupPrefix(string uri)
{
CheckIfOpen();
string prefix = _writer.LookupPrefix(uri);
if (prefix == null)
return ValueFactory.Create();
Expand All @@ -318,26 +341,24 @@ public IValue LookupPrefix(string uri)
[ContextMethod("Закрыть","Close")]
public IValue Close()
{
if(IsOpenForString())
if (_writer==null)
return ValueFactory.Create(String.Empty);

_writer.Flush();
_writer.Close();
Dispose();

if (IsOpenForString())
{
_writer.Flush();
_writer.Close();

Dispose();

var result = _stringBuffer.ToString();
_stringBuffer = null;

return ValueFactory.Create(result);
}
else
{
_writer.Flush();
_writer.Close();
Dispose();

return ValueFactory.Create();
return ValueFactory.Create(String.Empty);
}

}

private void ApplySettings(BslValue encodingOrSettings)
Expand Down Expand Up @@ -477,9 +498,7 @@ protected override void Dispose(bool disposing)

public void Dispose()
{
if (_writer != null)
_writer.Close();

_writer?.Close();
_writer = null;
}

Expand All @@ -490,5 +509,19 @@ public static XmlWriterImpl Create()
}

public XmlWriter GetNativeWriter() => _writer;

public static RuntimeException NotOpenException()
{
return new RuntimeException
("Приемник данных XML не открыт",
"XML data target is not opened");
}
public static RuntimeException CopyingNotSupportedException(XmlNodeType nodeType)
{
return new RuntimeException
($"Копирование узла типа {nodeType} не поддерживается",
$"Copying a node of type {nodeType} is not supported");
}

}
}
21 changes: 21 additions & 0 deletions tests/xmlwrite.os
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
ВсеТесты.Добавить("ТестДолжен_ЗаписатьТекущий_ИнструкцииОбработки");

ВсеТесты.Добавить("ТестДолжен_ЗаписатьТекущий_ОбъявлениеИТипДокумента");

ВсеТесты.Добавить("ТестДолжен_ПроверитьЗакрытиеПустого");
ВсеТесты.Добавить("ТестДолжен_ПроверитьТипВозвратаЗакрыть_ИзФайла");

Возврат ВсеТесты;

Expand Down Expand Up @@ -759,3 +762,21 @@
ЧтениеXML.Прочитать();
юТест.ПроверитьРавенство(ЧтениеXML.ТипУзла, ТипУзла, Сообщение);
КонецПроцедуры

Процедура ТестДолжен_ПроверитьЗакрытиеПустого() Экспорт
Запись = Новый ЗаписьXML;
Результат = Запись.Закрыть();

юТест.ПроверитьРавенство(ТипЗнч(Результат), Тип("Строка"));
юТест.ПроверитьРавенство(Результат, "");
КонецПроцедуры

Процедура ТестДолжен_ПроверитьТипВозвратаЗакрыть_ИзФайла() Экспорт
Запись = Новый ЗаписьXML;
ИмяФайла = юТест.ИмяВременногоФайла("xml");
Запись.ОткрытьФайл(ИмяФайла);
Результат = Запись.Закрыть();

юТест.ПроверитьРавенство(ТипЗнч(Результат), Тип("Строка"));
юТест.ПроверитьРавенство(Результат, "");
КонецПроцедуры