Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate cell writers for with/without reference attributes #29

Merged
merged 12 commits into from
Dec 26, 2023
Merged
139 changes: 82 additions & 57 deletions SpreadCheetah/CellValueWriters/Boolean/BooleanCellValueWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,27 @@ internal abstract class BooleanCellValueWriter : CellValueWriter
private static ReadOnlySpan<byte> BeginStyledBooleanCell => "<c t=\"b\" s=\""u8;
private static ReadOnlySpan<byte> BeginBooleanFormulaCell => "<c t=\"b\"><f>"u8;

protected abstract bool TryWriteCell(CellWriterState state);
protected abstract bool TryWriteCell(SpreadsheetBuffer buffer);
protected abstract bool TryWriteCellWithReference(CellWriterState state);
protected abstract bool TryWriteEndStyleValue(Span<byte> bytes, out int bytesWritten);
protected abstract bool TryWriteEndFormulaValue(Span<byte> bytes, out int bytesWritten);

public override bool TryWriteCell(in DataCell cell, DefaultStyling? defaultStyling, CellWriterState state)
public override bool TryWriteCell(in DataCell cell, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer)
{
return TryWriteCell(state);
return TryWriteCell(buffer);
}

public override bool TryWriteCell(in DataCell cell, StyleId styleId, CellWriterState state)
public override bool TryWriteCell(in DataCell cell, StyleId styleId, SpreadsheetBuffer buffer)
{
return TryWriteCell(styleId, state);
return TryWriteCell(styleId, buffer);
}

private bool TryWriteCell(StyleId styleId, CellWriterState state)
private bool TryWriteCell(StyleId styleId, SpreadsheetBuffer buffer)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (!state.WriteCellReferenceAttributes)
{
if (!BeginStyledBooleanCell.TryCopyTo(bytes, ref written)) return false;
}
else
{
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\" s=\""u8.TryCopyTo(bytes, ref written)) return false;
}

if (!BeginStyledBooleanCell.TryCopyTo(bytes, ref written)) return false;
if (!SpanHelper.TryWrite(styleId.Id, bytes, ref written)) return false;
if (!TryWriteEndStyleValue(bytes.Slice(written), out var endLength)) return false;
written += endLength;
Expand All @@ -48,50 +39,78 @@ private bool TryWriteCell(StyleId styleId, CellWriterState state)
return true;
}

public override bool TryWriteCell(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
public override bool TryWriteCell(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (styleId is null)
{
if (!BeginBooleanFormulaCell.TryCopyTo(bytes, ref written)) return false;
}
else
{
if (!BeginStyledBooleanCell.TryCopyTo(bytes, ref written)) return false;
if (!SpanHelper.TryWrite(styleId.Id, bytes, ref written)) return false;
if (!FormulaCellHelper.EndStyleBeginFormula.TryCopyTo(bytes, ref written)) return false;
}

if (!TryWriteFormulaCellStart(styleId, state, bytes, out var written)) return false;
if (!SpanHelper.TryWrite(formulaText, bytes, ref written)) return false;
if (!TryWriteEndFormulaValue(bytes.Slice(written), out var endLength)) return false;

buffer.Advance(written + endLength);
return true;
}

private static bool TryWriteFormulaCellStart(StyleId? styleId, CellWriterState state, Span<byte> bytes, out int bytesWritten)
public override bool TryWriteCellWithReference(in DataCell cell, DefaultStyling? defaultStyling, CellWriterState state)
{
bytesWritten = 0;
return TryWriteCellWithReference(state);
}

public override bool TryWriteCellWithReference(in DataCell cell, StyleId styleId, CellWriterState state)
{
return TryWriteCellWithReference(styleId, state);
}

private bool TryWriteCellWithReference(StyleId styleId, CellWriterState state)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (styleId is null)
{
if (!state.WriteCellReferenceAttributes)
return BeginBooleanFormulaCell.TryCopyTo(bytes, ref bytesWritten);
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\" s=\""u8.TryCopyTo(bytes, ref written)) return false;
if (!SpanHelper.TryWrite(styleId.Id, bytes, ref written)) return false;
if (!TryWriteEndStyleValue(bytes.Slice(written), out var endLength)) return false;
written += endLength;

if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\"><f>"u8.TryCopyTo(bytes, ref written)) return false;
buffer.Advance(written);
return true;
}

bytesWritten = written;
return true;
}
public override bool TryWriteCellWithReference(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (!state.WriteCellReferenceAttributes)
if (styleId is null)
{
if (!BeginStyledBooleanCell.TryCopyTo(bytes, ref written)) return false;
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\"><f>"u8.TryCopyTo(bytes, ref written)) return false;
}
else
{
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\" s=\""u8.TryCopyTo(bytes, ref written)) return false;
if (!SpanHelper.TryWrite(styleId.Id, bytes, ref written)) return false;
if (!FormulaCellHelper.EndStyleBeginFormula.TryCopyTo(bytes, ref written)) return false;
}

if (!SpanHelper.TryWrite(styleId.Id, bytes, ref written)) return false;
if (!FormulaCellHelper.EndStyleBeginFormula.TryCopyTo(bytes, ref written)) return false;
if (!SpanHelper.TryWrite(formulaText, bytes, ref written)) return false;
if (!TryWriteEndFormulaValue(bytes.Slice(written), out var endLength)) return false;

bytesWritten = written;
buffer.Advance(written + endLength);
return true;
}

Expand All @@ -112,48 +131,54 @@ public override bool TryWriteEndElement(in Cell cell, SpreadsheetBuffer buffer)
return false;
}

public override bool WriteFormulaStartElement(StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
public override bool WriteFormulaStartElement(StyleId? styleId, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (styleId is null)
{
if (!state.WriteCellReferenceAttributes)
{
if (!BeginBooleanFormulaCell.TryCopyTo(bytes, ref written)) return false;
buffer.Advance(written);
return true;
}

if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\"><f>"u8.TryCopyTo(bytes, ref written)) return false;

if (!BeginBooleanFormulaCell.TryCopyTo(bytes, ref written)) return false;
buffer.Advance(written);
return true;
}

if (!state.WriteCellReferenceAttributes)
{
if (!BeginStyledBooleanCell.TryCopyTo(bytes, ref written)) return false;
}
else
if (!BeginStyledBooleanCell.TryCopyTo(bytes, ref written)) return false;
if (!SpanHelper.TryWrite(styleId.Id, bytes, ref written)) return false;
if (!FormulaCellHelper.EndStyleBeginFormula.TryCopyTo(bytes, ref written)) return false;

buffer.Advance(written);
return true;
}

public override bool WriteFormulaStartElementWithReference(StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (styleId is null)
{
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\" s=\""u8.TryCopyTo(bytes, ref written)) return false;
if (!"\" t=\"b\"><f>"u8.TryCopyTo(bytes, ref written)) return false;

buffer.Advance(written);
return true;
}

if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\" s=\""u8.TryCopyTo(bytes, ref written)) return false;
if (!SpanHelper.TryWrite(styleId.Id, bytes, ref written)) return false;
if (!FormulaCellHelper.EndStyleBeginFormula.TryCopyTo(bytes, ref written)) return false;

buffer.Advance(written);
return true;
}

public override bool WriteStartElement(CellWriterState state) => TryWriteCell(state);

public override bool WriteStartElement(StyleId styleId, CellWriterState state) => TryWriteCell(styleId, state);
public override bool WriteStartElement(SpreadsheetBuffer buffer) => TryWriteCell(buffer);
public override bool WriteStartElement(StyleId styleId, SpreadsheetBuffer buffer) => TryWriteCell(styleId, buffer);
public override bool WriteStartElementWithReference(CellWriterState state) => TryWriteCellWithReference(state);
public override bool WriteStartElementWithReference(StyleId styleId, CellWriterState state) => TryWriteCellWithReference(styleId, state);

/// <summary>
/// Returns false because the value is written together with the end element in <see cref="TryWriteEndElement(in Cell, SpreadsheetBuffer)"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@ internal sealed class FalseBooleanCellValueWriter : BooleanCellValueWriter
private static ReadOnlySpan<byte> EndStyleFalseBooleanValue => "\"><v>0</v></c>"u8;
private static ReadOnlySpan<byte> EndFormulaFalseBooleanValue => "</f><v>0</v></c>"u8;

protected override bool TryWriteCell(CellWriterState state)
protected override bool TryWriteCell(SpreadsheetBuffer buffer)
{
var bytes = buffer.GetSpan();
var written = 0;

if (!FalseBooleanCell.TryCopyTo(bytes, ref written)) return false;

buffer.Advance(written);
return true;
}

protected override bool TryWriteCellWithReference(CellWriterState state)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (!state.WriteCellReferenceAttributes)
{
if (!FalseBooleanCell.TryCopyTo(bytes, ref written)) return false;
}
else
{
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\"><v>0</v></c>"u8.TryCopyTo(bytes, ref written)) return false;
}
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\"><v>0</v></c>"u8.TryCopyTo(bytes, ref written)) return false;

buffer.Advance(written);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@ internal sealed class TrueBooleanCellValueWriter : BooleanCellValueWriter
private static ReadOnlySpan<byte> EndStyleTrueBooleanValue => "\"><v>1</v></c>"u8;
private static ReadOnlySpan<byte> EndFormulaTrueBooleanValue => "</f><v>1</v></c>"u8;

protected override bool TryWriteCell(CellWriterState state)
protected override bool TryWriteCell(SpreadsheetBuffer buffer)
{
var bytes = buffer.GetSpan();
var written = 0;

if (!TrueBooleanCell.TryCopyTo(bytes, ref written)) return false;

buffer.Advance(written);
return true;
}

protected override bool TryWriteCellWithReference(CellWriterState state)
{
var buffer = state.Buffer;
var bytes = buffer.GetSpan();
var written = 0;

if (!state.WriteCellReferenceAttributes)
{
if (!TrueBooleanCell.TryCopyTo(bytes, ref written)) return false;
}
else
{
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\"><v>1</v></c>"u8.TryCopyTo(bytes, ref written)) return false;
}
if (!TryWriteCellStartWithReference(state, bytes, ref written)) return false;
if (!"\" t=\"b\"><v>1</v></c>"u8.TryCopyTo(bytes, ref written)) return false;

buffer.Advance(written);
return true;
Expand Down
18 changes: 12 additions & 6 deletions SpreadCheetah/CellValueWriters/CellValueWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ internal abstract class CellValueWriter
public static CellValueWriter FalseBoolean { get; } = new FalseBooleanCellValueWriter();
public static CellValueWriter String { get; } = new StringCellValueWriter();

public abstract bool TryWriteCell(in DataCell cell, DefaultStyling? defaultStyling, CellWriterState state);
public abstract bool TryWriteCell(in DataCell cell, StyleId styleId, CellWriterState state);
public abstract bool TryWriteCell(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state);
public abstract bool WriteStartElement(CellWriterState state);
public abstract bool WriteStartElement(StyleId styleId, CellWriterState state);
public abstract bool WriteFormulaStartElement(StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state);
public abstract bool TryWriteCell(in DataCell cell, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer);
public abstract bool TryWriteCell(in DataCell cell, StyleId styleId, SpreadsheetBuffer buffer);
public abstract bool TryWriteCell(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer);
public abstract bool TryWriteCellWithReference(in DataCell cell, DefaultStyling? defaultStyling, CellWriterState state);
public abstract bool TryWriteCellWithReference(in DataCell cell, StyleId styleId, CellWriterState state);
public abstract bool TryWriteCellWithReference(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state);
public abstract bool WriteStartElement(SpreadsheetBuffer buffer);
public abstract bool WriteStartElement(StyleId styleId, SpreadsheetBuffer buffer);
public abstract bool WriteStartElementWithReference(CellWriterState state);
public abstract bool WriteStartElementWithReference(StyleId styleId, CellWriterState state);
public abstract bool WriteFormulaStartElement(StyleId? styleId, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer);
public abstract bool WriteFormulaStartElementWithReference(StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state);
public abstract bool CanWriteValuePieceByPiece(in DataCell cell);
public abstract bool WriteValuePieceByPiece(in DataCell cell, SpreadsheetBuffer buffer, ref int valueIndex);
public abstract bool TryWriteEndElement(SpreadsheetBuffer buffer);
Expand Down
27 changes: 21 additions & 6 deletions SpreadCheetah/CellValueWriters/NullValueWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,33 @@ internal sealed class NullValueWriter : NullValueWriterBase
{
protected override int GetStyleId(StyleId styleId) => styleId.Id;

public override bool TryWriteCell(in DataCell cell, DefaultStyling? defaultStyling, CellWriterState state)
public override bool TryWriteCell(in DataCell cell, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer)
{
return TryWriteCell(state);
return TryWriteCell(buffer);
}

public override bool TryWriteCell(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
public override bool TryWriteCell(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer)
{
return TryWriteCell(formulaText, styleId?.Id, state);
return TryWriteCell(formulaText, styleId?.Id, buffer);
}

public override bool WriteFormulaStartElement(StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
public override bool TryWriteCellWithReference(in DataCell cell, DefaultStyling? defaultStyling, CellWriterState state)
{
return WriteFormulaStartElement(styleId?.Id, state);
return TryWriteCellWithReference(state);
}

public override bool TryWriteCellWithReference(string formulaText, in DataCell cachedValue, StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
{
return TryWriteCellWithReference(formulaText, styleId?.Id, state);
}

public override bool WriteFormulaStartElement(StyleId? styleId, DefaultStyling? defaultStyling, SpreadsheetBuffer buffer)
{
return WriteFormulaStartElement(styleId?.Id, buffer);
}

public override bool WriteFormulaStartElementWithReference(StyleId? styleId, DefaultStyling? defaultStyling, CellWriterState state)
{
return WriteFormulaStartElementWithReference(styleId?.Id, state);
}
}
Loading
Loading