diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a586324 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "docs/.shared"] + path = docs/.shared + url = https://github.com/amphp/website-shared diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..3262221 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +.bundle +_site diff --git a/docs/.shared b/docs/.shared new file mode 160000 index 0000000..b55f1af --- /dev/null +++ b/docs/.shared @@ -0,0 +1 @@ +Subproject commit b55f1aff6922b72073edd91dbf1a63b9239b405f diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 0000000..ada6383 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" +gem "github-pages" +gem "kramdown" +gem "jekyll-github-metadata" +gem "jekyll-relative-links" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 0000000..98b8aff --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,202 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.8) + i18n (~> 0.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + colorator (1.1.0) + ethon (0.10.1) + ffi (>= 1.3.0) + execjs (2.7.0) + faraday (0.12.1) + multipart-post (>= 1.2, < 3) + ffi (1.9.18) + forwardable-extended (2.6.0) + gemoji (3.0.0) + github-pages (138) + activesupport (= 4.2.8) + github-pages-health-check (= 1.3.3) + jekyll (= 3.4.3) + jekyll-avatar (= 0.4.2) + jekyll-coffeescript (= 1.0.1) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.9.2) + jekyll-gist (= 1.4.0) + jekyll-github-metadata (= 2.3.1) + jekyll-mentions (= 1.2.0) + jekyll-optional-front-matter (= 0.1.2) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.1.0) + jekyll-redirect-from (= 0.12.1) + jekyll-relative-links (= 0.4.0) + jekyll-sass-converter (= 1.5.0) + jekyll-seo-tag (= 2.2.3) + jekyll-sitemap (= 1.0.0) + jekyll-swiss (= 0.4.0) + jekyll-theme-architect (= 0.0.4) + jekyll-theme-cayman (= 0.0.4) + jekyll-theme-dinky (= 0.0.4) + jekyll-theme-hacker (= 0.0.4) + jekyll-theme-leap-day (= 0.0.4) + jekyll-theme-merlot (= 0.0.4) + jekyll-theme-midnight (= 0.0.4) + jekyll-theme-minimal (= 0.0.4) + jekyll-theme-modernist (= 0.0.4) + jekyll-theme-primer (= 0.1.8) + jekyll-theme-slate (= 0.0.4) + jekyll-theme-tactile (= 0.0.4) + jekyll-theme-time-machine (= 0.0.4) + jekyll-titles-from-headings (= 0.1.5) + jemoji (= 0.8.0) + kramdown (= 1.13.2) + liquid (= 3.0.6) + listen (= 3.0.6) + mercenary (~> 0.3) + minima (= 2.1.1) + rouge (= 1.11.1) + terminal-table (~> 1.4) + github-pages-health-check (1.3.3) + addressable (~> 2.3) + net-dns (~> 0.8) + octokit (~> 4.0) + public_suffix (~> 2.0) + typhoeus (~> 0.7) + html-pipeline (2.6.0) + activesupport (>= 2) + nokogiri (>= 1.4) + i18n (0.8.1) + jekyll (3.4.3) + addressable (~> 2.4) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 3.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 1.7) + safe_yaml (~> 1.0) + jekyll-avatar (0.4.2) + jekyll (~> 3.0) + jekyll-coffeescript (1.0.1) + coffee-script (~> 2.2) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.9.2) + jekyll (~> 3.3) + jekyll-gist (1.4.0) + octokit (~> 4.2) + jekyll-github-metadata (2.3.1) + jekyll (~> 3.1) + octokit (~> 4.0, != 4.4.0) + jekyll-mentions (1.2.0) + activesupport (~> 4.0) + html-pipeline (~> 2.3) + jekyll (~> 3.0) + jekyll-optional-front-matter (0.1.2) + jekyll (~> 3.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.1.0) + jekyll (~> 3.0) + jekyll-redirect-from (0.12.1) + jekyll (~> 3.3) + jekyll-relative-links (0.4.0) + jekyll (~> 3.3) + jekyll-sass-converter (1.5.0) + sass (~> 3.4) + jekyll-seo-tag (2.2.3) + jekyll (~> 3.3) + jekyll-sitemap (1.0.0) + jekyll (~> 3.3) + jekyll-swiss (0.4.0) + jekyll-theme-architect (0.0.4) + jekyll (~> 3.3) + jekyll-theme-cayman (0.0.4) + jekyll (~> 3.3) + jekyll-theme-dinky (0.0.4) + jekyll (~> 3.3) + jekyll-theme-hacker (0.0.4) + jekyll (~> 3.3) + jekyll-theme-leap-day (0.0.4) + jekyll (~> 3.3) + jekyll-theme-merlot (0.0.4) + jekyll (~> 3.3) + jekyll-theme-midnight (0.0.4) + jekyll (~> 3.3) + jekyll-theme-minimal (0.0.4) + jekyll (~> 3.3) + jekyll-theme-modernist (0.0.4) + jekyll (~> 3.3) + jekyll-theme-primer (0.1.8) + jekyll (~> 3.3) + jekyll-theme-slate (0.0.4) + jekyll (~> 3.3) + jekyll-theme-tactile (0.0.4) + jekyll (~> 3.3) + jekyll-theme-time-machine (0.0.4) + jekyll (~> 3.3) + jekyll-titles-from-headings (0.1.5) + jekyll (~> 3.3) + jekyll-watch (1.5.0) + listen (~> 3.0, < 3.1) + jemoji (0.8.0) + activesupport (~> 4.0) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0) + kramdown (1.13.2) + liquid (3.0.6) + listen (3.0.6) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9.7) + mercenary (0.3.6) + mini_portile2 (2.1.0) + minima (2.1.1) + jekyll (~> 3.3) + minitest (5.10.2) + multipart-post (2.0.0) + net-dns (0.8.0) + nokogiri (1.7.2) + mini_portile2 (~> 2.1.0) + octokit (4.7.0) + sawyer (~> 0.8.0, >= 0.5.3) + pathutil (0.14.0) + forwardable-extended (~> 2.6) + public_suffix (2.0.5) + rb-fsevent (0.9.8) + rb-inotify (0.9.8) + ffi (>= 0.5.0) + rouge (1.11.1) + safe_yaml (1.0.4) + sass (3.4.24) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (0.8.0) + ethon (>= 0.8.0) + tzinfo (1.2.3) + thread_safe (~> 0.1) + unicode-display_width (1.2.1) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages + jekyll-github-metadata + jekyll-relative-links + kramdown + +BUNDLED WITH + 1.15.0 diff --git a/docs/README.md b/docs/README.md index 9bf3986..5c6be10 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,75 +1,25 @@ -# Streams +# Documentation -Streams are an abstraction over ordered sequences of bytes. This package provides the fundamental interfaces `InputStream` and `OutputStream`. +This directory contains the documentation for `amphp/byte-stream`. Documentation and code are bundled within a single repository for easier maintenance. Additionally, this preserves the documentation for older versions. -## InputStream +## Reading -`InputStream` offers a single method: `read()`. It returns a promise that gets either resolved with a `string` or `null`. `null` indicates that the stream has ended. +You can read this documentation either directly on GitHub or on our website. While the website will always contain the latest version, viewing on GitHub also works with older versions. -### Example +## Writing -This example shows a simple `InputStream` consumption that buffers the complete stream contents inside a coroutine. +Our documentation is built using Jekyll. -```php -$inputStream = ...; -$buffer = ""; - -while (($chunk = yield $inputStream->read()) !== null) { - $buffer .= $chunk; -} - -// do something with $buffer +``` +sudo gem install bundler jekyll ``` -> **Note:** While buffering a stream that way is extremely straightforward, you might want to use `yield new Message($inputStream)` to buffer a complete `InputStream`, making it even easier. - -### Implementations - -This package offers some basic implementations, other libraries might provide even more implementations, such as [`amphp/socket`](https://github.com/amphp/socket). - - * [`InMemoryStream`](./in-memory-stream.md) - * [`IteratorStream`](./iterator-stream.md) - * [`Message`](./message.md) - * [`ResourceInputStream`](./resource-streams.md) - * [`ZlibInputStream`](./compression-streams.md) - -## OutputStream - -`OutputStream` offers two methods: `write()` and `end()`. - -### `write()` - -`write()` writes the given string to the stream. The returned `Promise` might be used to wait for completion. Waiting for completion allows writing only as fast as the underlying stream can write and potentially send over a network. TCP streams will resolve the returned `Promise` immediately as long as the write buffer isn't full. - -The write order is always ensured, even if the writer doesn't wait on the promise. - -> **Tip:** Use `Amp\Promise\rethrow` on the returned `Promise` if you do not wait on it to get notified about write errors instead of silently doing nothing on errors. - -### `end()` - -`end()` marks the stream as ended, optionally writing a last data chunk before. TCP streams might close the underlying stream for writing, but MUST NOT close it. Instead, all resources should be freed and actual resource handles be closed by PHP's garbage collection process. - -## Example - -This example uses the previous example to read from a stream and simply writes all data to an `OutputStream`. - -```php -$inputStream = ...; -$outputStream = ...; -$buffer = ""; - -while (($chunk = yield $inputStream->read()) !== null) { - yield $outputStream->write($chunk); -} - -yield $outputStream->end(); ``` +git submodule init +git submodule update -### Implementations - -This package offers some basic implementations, other libraries might provide even more implementations, such as [`amphp/socket`](https://github.com/amphp/socket). - - * [`Parser`](./parser.md) - * [`ResourceOutputStream`](./resource-streams.md) - * [`ZlibOutputStream`](./compression-streams.md) +cd docs +bundle install --path vendor/bundle +bundle exec jekyll serve +``` diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..2220bf7 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,31 @@ +kramdown: + input: GFM + toc_levels: 2..3 + +baseurl: "/byte-stream" +layouts_dir: ".shared/layout" + +exclude: ["Gemfile", "Gemfile.lock", "README.md", "vendor"] +include: [".shared"] + +repository: amphp/byte-stream +gems: + - "jekyll-github-metadata" + - "jekyll-relative-links" + +defaults: + - scope: + path: "" + type: "pages" + values: + layout: "docs" + +asset_path: "/byte-stream/.shared/asset" + +navigation: + - resource-streams + - in-memory-stream + - iterator-stream + - compression-streams + - message + - parser diff --git a/docs/compression-streams.md b/docs/compression-streams.md index 69811e8..22b27af 100644 --- a/docs/compression-streams.md +++ b/docs/compression-streams.md @@ -1,5 +1,7 @@ -# Compression Streams - +--- +title: Compression Streams +permalink: /compression-streams +--- This package implements compression and decompression streams based on Zlib. `ZlibOutputStream` can be used for compression, while `ZlibInputStream` can be used for decompression. Both can simply wrap an existing stream to apply them. Both accept an `$encoding` and `$options` parameter in their constructor. ## Examples diff --git a/docs/in-memory-stream.md b/docs/in-memory-stream.md index 3e6830f..7e72b8b 100644 --- a/docs/in-memory-stream.md +++ b/docs/in-memory-stream.md @@ -1,5 +1,7 @@ -# InMemoryStream - +--- +title: InMemoryStream +permalink: /in-memory-stream +--- An `InMemoryStream` allows creating an `InputStream` from a single known string chunk. This is helpful if the complete stream contents are already known. ```php diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..e9c9e0e --- /dev/null +++ b/docs/index.md @@ -0,0 +1,77 @@ +--- +title: Overview +permalink: / +--- +Streams are an abstraction over ordered sequences of bytes. This package provides the fundamental interfaces `InputStream` and `OutputStream`. + +## InputStream + +`InputStream` offers a single method: `read()`. It returns a promise that gets either resolved with a `string` or `null`. `null` indicates that the stream has ended. + +### Example + +This example shows a simple `InputStream` consumption that buffers the complete stream contents inside a coroutine. + +```php +$inputStream = ...; +$buffer = ""; + +while (($chunk = yield $inputStream->read()) !== null) { + $buffer .= $chunk; +} + +// do something with $buffer +``` + +> **Note:** While buffering a stream that way is extremely straightforward, you might want to use `yield new Message($inputStream)` to buffer a complete `InputStream`, making it even easier. + +### Implementations + +This package offers some basic implementations, other libraries might provide even more implementations, such as [`amphp/socket`](https://github.com/amphp/socket). + + * [`InMemoryStream`](./in-memory-stream.md) + * [`IteratorStream`](./iterator-stream.md) + * [`Message`](./message.md) + * [`ResourceInputStream`](./resource-streams.md) + * [`ZlibInputStream`](./compression-streams.md) + +## OutputStream + +`OutputStream` offers two methods: `write()` and `end()`. + +### `write()` + +`write()` writes the given string to the stream. The returned `Promise` might be used to wait for completion. Waiting for completion allows writing only as fast as the underlying stream can write and potentially send over a network. TCP streams will resolve the returned `Promise` immediately as long as the write buffer isn't full. + +The write order is always ensured, even if the writer doesn't wait on the promise. + +> **Tip:** Use `Amp\Promise\rethrow` on the returned `Promise` if you do not wait on it to get notified about write errors instead of silently doing nothing on errors. + +### `end()` + +`end()` marks the stream as ended, optionally writing a last data chunk before. TCP streams might close the underlying stream for writing, but MUST NOT close it. Instead, all resources should be freed and actual resource handles be closed by PHP's garbage collection process. + +## Example + +This example uses the previous example to read from a stream and simply writes all data to an `OutputStream`. + +```php +$inputStream = ...; +$outputStream = ...; +$buffer = ""; + +while (($chunk = yield $inputStream->read()) !== null) { + yield $outputStream->write($chunk); +} + +yield $outputStream->end(); +``` + +### Implementations + +This package offers some basic implementations, other libraries might provide even more implementations, such as [`amphp/socket`](https://github.com/amphp/socket). + + * [`Parser`](./parser.md) + * [`ResourceOutputStream`](./resource-streams.md) + * [`ZlibOutputStream`](./compression-streams.md) + diff --git a/docs/iterator-stream.md b/docs/iterator-stream.md index 9e00367..94a00d0 100644 --- a/docs/iterator-stream.md +++ b/docs/iterator-stream.md @@ -1,5 +1,7 @@ -# IteratorStream - +--- +title: IteratorStream +permalink: /iterator-stream +--- `IteratorStream` allows converting an `Amp\Iterator` that yields strings into an `InputStream`. ```php diff --git a/docs/message.md b/docs/message.md index 9b4aa84..7060534 100644 --- a/docs/message.md +++ b/docs/message.md @@ -1,5 +1,7 @@ -# Message - +--- +title: Message +permalink: /message +--- `Message` implements both `InputStream` _and_ `Promise`. This allows consuming a message either in chunks (streaming) or consume everything at once (buffering). ## Buffering diff --git a/docs/parser.md b/docs/parser.md index 3198f10..4873393 100644 --- a/docs/parser.md +++ b/docs/parser.md @@ -1,3 +1,5 @@ -# Parser - +--- +title: Parser +permalink: /parser +--- TBD.