/// <summary> /// Load program from ascii, bytecode or protected stream. /// </summary> /// <param name="stream">Program stream</param> /// <param name="rebuildLineNumber">Should rebuild line numbers</param> public void Load(Stream stream, bool rebuildLineNumber = true) { Erase(); var programMode = FindDocumentType(stream); Bytecode.WriteByte((byte)programMode); switch (programMode) { case ProgramMode.Binary: stream.CopyTo(Bytecode); break; case ProgramMode.Protected: _protected = AllowProtect; ProtectedProgramEncoder.Decode(stream).CopyTo(Bytecode); break; case ProgramMode.Ascii: Merge(stream); break; } if (rebuildLineNumber && programMode != ProgramMode.Ascii) { RebuildLineNumbers(); } }
/// <summary> /// Save the program to stream stream in defined mode. /// </summary> /// <param name="stream">Stream to which to save</param> /// <param name="mode">Mode in which to save program</param> public void SaveTo(Stream stream, ProgramMode mode) { if (mode != ProgramMode.Protected && _protected) { throw new ReplRuntimeException(ReplExceptionCode.IllegalFunctionCall); } var current = Bytecode.Position; // skip first \x00 in bytecode Bytecode.Seek(1, SeekOrigin.Begin); switch (mode) { case ProgramMode.Binary: Bytecode.CopyTo(stream); break; case ProgramMode.Protected: ProtectedProgramEncoder.Encode(Bytecode).CopyTo(stream); break; case ProgramMode.Ascii: while (true) { var output = Tokeniser.DetokeniseLine(Bytecode); if (output.LineNumber == -1 || output.LineNumber > MaxLineNumber) { break; } stream.Write(output.Text); } break; } Bytecode.Seek(current, SeekOrigin.Begin); }