using System; using System.Buffers; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Nyanbyte.Minime.Processing; public class CssProcessor : IProcessor { internal const string L_COMMENT_OPEN = "/*", L_COMMENT_CLOSE = "*/"; internal const char L_STRING = '"', L_STRING_C = '\'', L_SEMI = ';'; public async Task Execute(FileContext ctx, CancellationToken cancellation) { var write = ctx.Output; var read = ctx.Input; bool isQuote = false, isComment = false; Memory<char> buf = MemoryPool<char>.Shared.Rent(32 * 1024).Memory; int len = await read.ReadBlockAsync(buf, cancellation); for (int i = 0; i < len; i++) { char c = buf.Span[i]; if (isComment) { if (buf.Slice(i, 2).Span.SequenceEqual(L_COMMENT_CLOSE)) { isComment = false; ++i; continue; } } switch (c) { case L_STRING or L_STRING_C: isQuote = !isQuote; continue; case ' ': if (!isQuote) continue; await write.WriteAsync(c); break; case '\n': continue; case '/': if (!isQuote) { if (buf.Slice(i, 2).Span.SequenceEqual(L_COMMENT_OPEN)) { isComment = true; ++i; continue; } } continue; default: if (isQuote) { await write.WriteAsync(c); continue; } break; } } } }