Skip to content

Commit

Permalink
Improve xml output
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyalIcing committed Dec 14, 2023
1 parent c1ff919 commit 1a5d8a8
Show file tree
Hide file tree
Showing 7 changed files with 401 additions and 339 deletions.
18 changes: 16 additions & 2 deletions lib/components_guide/wasm/examples/podcast_feed/podcast_feed.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ defmodule ComponentsGuide.Wasm.PodcastFeed do
# Global.import()
# wasm_import(:datasource, populate_episode_at_index: Orb.DSL.funcp(name: :datasource_populate_episode, params: I32))

defmodule StdOut do
use Orb.Import

defw(flush(read_ptr: I32.UnsafePointer, byte_count: I32), nil)
end

defmodule Datasource do
use Orb.Import

Expand All @@ -53,6 +59,10 @@ defmodule ComponentsGuide.Wasm.PodcastFeed do
defw(write_episode_id(episode_id: EpisodeID, write_ptr: I32.UnsafePointer), I32)
defw(write_episode_title(episode_id: EpisodeID, write_ptr: I32.UnsafePointer), I32)
# defw(write_episode_author(episode_id: EpisodeID, write_ptr: I32.UnsafePointer), I32)
# TODO: what happens if it wants to write more than the memory available?
# Yet another reason to have arenas for title, description, etc.
# Or have to use a proper malloc approach.
# Or have to flush before each write, and rewind bump_offset to beginning.
defw(write_episode_description(episode_id: EpisodeID, write_ptr: I32.UnsafePointer), I32)
defw(write_episode_link_url(episode_id: EpisodeID, write_ptr: I32.UnsafePointer), I32)
defw(write_episode_mp3_url(episode_id: EpisodeID, write_ptr: I32.UnsafePointer), I32)
Expand All @@ -72,6 +82,10 @@ defmodule ComponentsGuide.Wasm.PodcastFeed do
importw(Datasource, :datasource)

# SilverOrb.Arena.def(DatasourceArena, pages: 1)
# Used by url attribute in <enclosure url="…">
SilverOrb.Arena.def(WriteBuffer, pages: 1)
# Attributes must have <&" escaped.
SilverOrb.Arena.def(EscapeXMLBuffer, pages: byte_size("&amp;"))

# There are a few ways to implement this:
# 1. Pass every episode in as some sort of data structure. e.g.
Expand Down Expand Up @@ -134,7 +148,7 @@ defmodule ComponentsGuide.Wasm.PodcastFeed do
build! do
~S[<?xml version="1.0" encoding="UTF-8"?>\n]

XML.open(:rss,
XML.open_newline(:rss,
version: "2.0",
"xmlns:itunes": "http://www.itunes.com/dtds/podcast-1.0.dtd",
"xmlns:googleplay": "http://www.google.com/schemas/play-podcasts/1.0",
Expand All @@ -146,7 +160,7 @@ defmodule ComponentsGuide.Wasm.PodcastFeed do
# This then causes the module to clear its local memory, resetting the bump
# offset to the very beginning again.

XML.open(:channel)
XML.open_newline(:channel)
XML.element(:title, @title)

XML.element(:description, @description)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ defmodule ComponentsGuide.Wasm.PodcastFeed.XMLFormatter do
])
end

def open_newline(tag, attributes \\ []) when is_atom(tag) do
Orb.InstructionSequence.new(:memory_effect, [
open(tag, attributes),
append!(ascii: ?\n)
])
end

def close_newline(tag) when is_atom(tag) do
xml_close_newline(Orb.DSL.const(Atom.to_string(tag)))
end
Expand Down
9 changes: 6 additions & 3 deletions test/components_guide/wasm/examples/podcast_feed_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ defmodule ComponentsGuide.Wasm.PodcastFeed.Test do
assert "Episode 2" = xml_text_content(item2, "//itunes:title[1]")
assert "Description for 1" = xml_text_content(item1, "//description[1]")
assert "Description for 2" = xml_text_content(item2, "//description[1]")

# <enclosure url="${bunnyEpisodeURL(episodeID)}" length="${feedItem.mp3ByteCount}" type="audio/mpeg"/>
assert "Description for 2" = xml_xpath(item1, "//enclosure[1]")
end

defp xml_parse(xml) do
Expand Down Expand Up @@ -131,7 +134,7 @@ defmodule ComponentsGuide.Wasm.PodcastFeed.Test do

defp do_xml_text_content(_, acc), do: acc

@tag :skip
# @tag :skip
test "output optimized wasm" do
path_wasm = Path.join(__DIR__, "podcast_feed_xml.wasm")
path_wat = Path.join(__DIR__, "podcast_feed_xml.wat")
Expand All @@ -142,10 +145,10 @@ defmodule ComponentsGuide.Wasm.PodcastFeed.Test do
System.cmd("wasm-opt", [path_wasm, "-o", path_opt_wasm, "-O"])

%{size: size} = File.stat!(path_wasm)
assert size == 2419
assert size == 2418

%{size: size} = File.stat!(path_opt_wasm)
assert size == 1868
assert size == 1909

{wat, 0} = System.cmd("wasm2wat", [path_wasm])
File.write!(path_wat, wat)
Expand Down
Binary file modified test/components_guide/wasm/examples/podcast_feed_xml.wasm
Binary file not shown.
Loading

0 comments on commit 1a5d8a8

Please sign in to comment.