Skip to content

Commit d201b54

Browse files
authored
fix EvilBeaver#1679: добавлен метод ОткрытьПоток() объекта ЧтениеJSON
2 parents a541e3e + 021d90f commit d201b54

3 files changed

Lines changed: 76 additions & 55 deletions

File tree

src/OneScript.StandardLibrary/Binary/FileStreamContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace OneScript.StandardLibrary.Binary
2222
/// Следует учитывать, что помимо буферизации существует кэширование чтения и записи файлов в операционной системе, на которое невозможно повлиять программно.
2323
/// </summary>
2424
[ContextClass("ФайловыйПоток", "FileStream")]
25-
public class FileStreamContext : AutoContext<FileStreamContext>, IStreamWrapper, IDisposable
25+
public class FileStreamContext : AutoContext<FileStreamContext>, IDisposable, IStreamWrapper
2626
{
2727

2828
private readonly FileStream _underlyingStream;

src/OneScript.StandardLibrary/Json/JSONReader.cs

Lines changed: 38 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ This Source Code Form is subject to the terms of the
55
at http://mozilla.org/MPL/2.0/.
66
----------------------------------------------------------*/
77

8-
using System;
9-
using System.IO;
108
using Newtonsoft.Json;
119
using OneScript.Commons;
1210
using OneScript.Contexts;
1311
using OneScript.Exceptions;
12+
using OneScript.StandardLibrary.Binary;
1413
using OneScript.StandardLibrary.Text;
1514
using ScriptEngine.Machine;
1615
using ScriptEngine.Machine.Contexts;
16+
using System;
17+
using System.IO;
1718

1819
namespace OneScript.StandardLibrary.Json
1920
{
@@ -40,7 +41,6 @@ public override bool Read()
4041
}
4142

4243
/// <summary>
43-
///
4444
/// Предназначен для последовательного чтения JSON-данных из файла или строки.
4545
/// </summary>
4646
[ContextClass("ЧтениеJSON", "JSONReader")]
@@ -50,7 +50,6 @@ public class JSONReader : AutoContext<JSONReader>
5050
private JsonReaderInternal _reader;
5151

5252
/// <summary>
53-
///
5453
/// Возвращает true если для объекта чтения json был задан текст для парсинга.
5554
/// </summary>
5655
private bool IsOpen() => _reader != null;
@@ -71,49 +70,25 @@ public static JSONReader Constructor()
7170
}
7271

7372
/// <summary>
74-
///
7573
/// Указывает на позицию, находящуюся сразу после прочитанного значения.
7674
/// При ошибке чтение остается на позиции последнего успешно считанного символа.
7775
/// </summary>
7876
/// <value>Число (Number), Неопределено (Undefined)</value>
7977
[ContextProperty("ТекущаяПозиция", "CurrentPosition")]
8078
public IValue CurrentPosition
81-
{
82-
get
83-
{
84-
if (IsOpen())
85-
{
86-
return ValueFactory.Create(_reader.LinePosition);
87-
}
88-
89-
return ValueFactory.Create(); // Неопределено
90-
}
91-
}
79+
=> IsOpen() ? ValueFactory.Create(_reader.LinePosition) : ValueFactory.Create();
9280

9381
/// <summary>
94-
///
9582
/// Указывает на позицию сразу после прочитанного значения.
9683
/// Например, перед чтением первого элемента - 0, после чтения первого элемента -1 .
9784
/// </summary>
9885
/// <value>Число (Number), Неопределено (Undefined)</value>
9986
[ContextProperty("ТекущаяСтрока", "CurrentLine")]
10087
public IValue CurrentLine
101-
{
102-
get
103-
{
104-
if (IsOpen())
105-
{
106-
return ValueFactory.Create(_reader.LineNumber);
107-
}
108-
109-
return ValueFactory.Create(); // Неопределено
110-
}
111-
}
88+
=> IsOpen() ? ValueFactory.Create(_reader.LineNumber) : ValueFactory.Create();
11289

11390
/// <summary>
114-
///
11591
/// Содержит текущее значение:
116-
///
11792
/// - Число - если ТипТекущегоЗначения имеет значение Число;
11893
/// - Строка - если ТипТекущегоЗначения имеет одно из следующих значений:
11994
/// - Комментарий,
@@ -160,15 +135,13 @@ public IValue CurrentValue
160135

161136
default:
162137
throw JSONReaderException.CannotGetValue();
163-
;
164138
}
165139
}
166140
}
167141

168142
public object ReaderValue => _reader.Value;
169143

170144
/// <summary>
171-
///
172145
/// Тип текущего значения в документе JSON во внутреннем формате.
173146
/// null - если чтение еще не началось или достигнут конец файла.
174147
/// </summary>
@@ -183,7 +156,6 @@ public JsonToken CurrentJsonTokenType
183156
}
184157

185158
/// <summary>
186-
///
187159
/// Тип текущего значения в документе JSON.
188160
/// Неопределено - если чтение еще не началось или достигнут конец файла.
189161
/// </summary>
@@ -217,10 +189,8 @@ public JSONValueTypeEnum CurrentValueType
217189
}
218190

219191
/// <summary>
220-
///
221192
/// Завершает чтение текста JSON из файла или строки.
222193
/// </summary>
223-
///
224194
[ContextMethod("Закрыть", "Close")]
225195
public void Close()
226196
{
@@ -232,28 +202,25 @@ public void Close()
232202
}
233203

234204
/// <summary>
235-
///
236-
/// Открывает JSON-файл для чтения данным объектом. Если перед вызовом данного метода уже производилось чтение JSON из другого файла или строки, то чтение прекращается и объект инициализируется для чтения из указанного файла.
205+
/// Открывает JSON-файл для чтения данным объектом.
206+
/// Если перед вызовом данного метода уже производилось чтение JSON из другого файла или строки,
207+
/// то чтение прекращается и объект инициализируется для чтения из указанного файла.
237208
/// </summary>
238-
///
239209
/// <param name="JSONFileName">
240210
/// Имя файла, содержащего текст JSON. </param>
241211
/// <param name="encoding">
242212
/// Позволяет задать кодировку входного файла.</param>
243213
[ContextMethod("ОткрытьФайл", "OpenFile")]
244214
public void OpenFile(string JSONFileName, IValue encoding = null)
245215
{
246-
if (IsOpen())
247-
Close();
216+
Close();
248217

249218
StreamReader _fileReader;
250219

251220
try
252-
{
253-
if (encoding != null)
254-
_fileReader = FileOpener.OpenReader(JSONFileName, TextEncodingEnum.GetEncoding(encoding));
255-
else
256-
_fileReader = FileOpener.OpenReader(JSONFileName, System.Text.Encoding.UTF8);
221+
{
222+
var enc = encoding != null ? TextEncodingEnum.GetEncoding(encoding) : System.Text.Encoding.UTF8;
223+
_fileReader = FileOpener.OpenReader(JSONFileName, enc);
257224
}
258225
catch (Exception e)
259226
{
@@ -266,11 +233,35 @@ public void OpenFile(string JSONFileName, IValue encoding = null)
266233
};
267234
}
268235

236+
/// <summary>
237+
/// Устанавливает поток для чтения JSON данным объектом.
238+
/// Если перед вызовом данного метода уже производилось чтение JSON из другого файла, строки или потока,
239+
/// то чтение прекращается и объект инициализируется для чтения из указанного потока.
240+
/// </summary>
241+
/// <param name="streamContext">
242+
/// Поток для чтения текста JSON.</param>
243+
/// <param name="encoding">
244+
/// Позволяет задать кодировку входного потока.</param>
245+
[ContextMethod("ОткрытьПоток", "OpenStream")]
246+
public void OpenStream(IStreamWrapper streamContext, IValue encoding = null)
247+
{
248+
Close();
249+
250+
var stream = streamContext?.GetUnderlyingStream()
251+
?? throw new ArgumentNullException(nameof(streamContext));
252+
253+
var enc = encoding != null ? TextEncodingEnum.GetEncoding(encoding) : System.Text.Encoding.UTF8;
254+
255+
_reader = new JsonReaderInternal(new StreamReader(stream, enc, leaveOpen:true))
256+
{
257+
SupportMultipleContent = true
258+
};
259+
}
260+
269261
/// <summary>
270262
/// Если текущее значение – начало массива или объекта, то пропускает его содержимое и конец.
271263
/// Для остальных типов значений работает аналогично методу Прочитать().
272264
/// </summary>
273-
///
274265
[ContextMethod("Пропустить", "Skip")]
275266
public bool Skip()
276267
{
@@ -287,29 +278,22 @@ public bool Skip()
287278
/// <summary>
288279
/// Выполняет чтение значения JSON.
289280
/// </summary>
290-
///
291281
[ContextMethod("Прочитать", "Read")]
292282
public bool Read()
293283
{
294284
CheckIfOpen();
295285
return _reader.Read();
296-
297286
}
298287

299288
/// <summary>
300-
///
301289
/// Устанавливает строку, содержащую текст JSON для чтения данным объектом. Если перед вызовом данного метода уже производилось чтение JSON из другого файла или строки, то чтение прекращается и объект инициализируется для чтения из указанной строки.
302290
/// </summary>
303-
///
304291
/// <param name="JSONString">
305292
/// Строка, содержащая текст в формате JSON. </param>
306-
///
307-
///
308293
[ContextMethod("УстановитьСтроку", "SetString")]
309294
public void SetString(string JSONString)
310295
{
311-
if (IsOpen())
312-
Close();
296+
Close();
313297

314298
_reader = new JsonReaderInternal(new StringReader(JSONString))
315299
{

tests/json/test-json_reader.os

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
СписокТестов.Добавить("Тест_Должен_ПроверитьПропускНезавершенногоМассива");
2525
СписокТестов.Добавить("Тест_Должен_ПроверитьПропускМассиваСВложенными");
2626
СписокТестов.Добавить("Тест_Должен_ПроверитьПропускОбъектаСВложениями");
27+
28+
СписокТестов.Добавить("Тест_Должен_ПроверитьОткрытиеПотока");
29+
СписокТестов.Добавить("Тест_Должен_ПроверитьПовторноеОткрытиеПотока");
30+
СписокТестов.Добавить("Тест_Должен_ПроверитьСохранениеПотокаПослеЗакрытияЧтения");
2731
Возврат СписокТестов;
2832

2933
КонецФункции
@@ -219,3 +223,36 @@
219223
юТест.ПроверитьРавенство(ТипЗначенияJSON.Число, Чтение.ТипТекущегоЗначения);
220224
юТест.ПроверитьРавенство(5, Чтение.ТекущееЗначение);
221225
КонецПроцедуры
226+
227+
Процедура Тест_Должен_ПроверитьОткрытиеПотока() Экспорт
228+
БДД = ПолучитьБуферДвоичныхДанныхИзСтроки("{""ответ"":42}");
229+
Поток = Новый ПотокВПамяти(БДД);
230+
Чтение = Новый ЧтениеJSON;
231+
Чтение.ОткрытьПоток(Поток);
232+
Json = ПрочитатьJSON(Чтение);
233+
234+
юТест.ПроверитьРавенство(42, Json.Ответ);
235+
КонецПроцедуры
236+
237+
Процедура Тест_Должен_ПроверитьПовторноеОткрытиеПотока() Экспорт
238+
БДД = ПолучитьБуферДвоичныхДанныхИзСтроки("{""ответ"":42}");
239+
Поток = Новый ПотокВПамяти(БДД);
240+
Чтение = Новый ЧтениеJSON;
241+
Чтение.ОткрытьПоток(Поток);
242+
Чтение.ОткрытьПоток(Поток); // повторно
243+
Json = ПрочитатьJSON(Чтение);
244+
245+
юТест.ПроверитьРавенство(42, Json.Ответ);
246+
КонецПроцедуры
247+
248+
Процедура Тест_Должен_ПроверитьСохранениеПотокаПослеЗакрытияЧтения() Экспорт
249+
БДД = ПолучитьБуферДвоичныхДанныхИзСтроки("{""ответ"":42}");
250+
Поток = Новый ПотокВПамяти(БДД);
251+
Чтение = Новый ЧтениеJSON;
252+
Чтение.ОткрытьПоток(Поток);
253+
Чтение.Закрыть();
254+
Чтение.ОткрытьПоток(Поток); // Поток должен остаться открытым
255+
Json = ПрочитатьJSON(Чтение);
256+
257+
юТест.ПроверитьРавенство(42, Json.Ответ);
258+
КонецПроцедуры

0 commit comments

Comments
 (0)