Version 1
[yaffs-website] / vendor / zendframework / zend-diactoros / src / AbstractSerializer.php
diff --git a/vendor/zendframework/zend-diactoros/src/AbstractSerializer.php b/vendor/zendframework/zend-diactoros/src/AbstractSerializer.php
new file mode 100644 (file)
index 0000000..9ee9afd
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @see       http://github.com/zendframework/zend-diactoros for the canonical source repository
+ * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
+ */
+
+namespace Zend\Diactoros;
+
+use Psr\Http\Message\StreamInterface;
+use UnexpectedValueException;
+
+/**
+ * Provides base functionality for request and response de/serialization
+ * strategies, including functionality for retrieving a line at a time from
+ * the message, splitting headers from the body, and serializing headers.
+ */
+abstract class AbstractSerializer
+{
+    const CR  = "\r";
+    const EOL = "\r\n";
+    const LF  = "\n";
+
+    /**
+     * Retrieve a single line from the stream.
+     *
+     * Retrieves a line from the stream; a line is defined as a sequence of
+     * characters ending in a CRLF sequence.
+     *
+     * @param StreamInterface $stream
+     * @return string
+     * @throws UnexpectedValueException if the sequence contains a CR or LF in
+     *     isolation, or ends in a CR.
+     */
+    protected static function getLine(StreamInterface $stream)
+    {
+        $line    = '';
+        $crFound = false;
+        while (! $stream->eof()) {
+            $char = $stream->read(1);
+
+            if ($crFound && $char === self::LF) {
+                $crFound = false;
+                break;
+            }
+
+            // CR NOT followed by LF
+            if ($crFound && $char !== self::LF) {
+                throw new UnexpectedValueException('Unexpected carriage return detected');
+            }
+
+            // LF in isolation
+            if (! $crFound && $char === self::LF) {
+                throw new UnexpectedValueException('Unexpected line feed detected');
+            }
+
+            // CR found; do not append
+            if ($char === self::CR) {
+                $crFound = true;
+                continue;
+            }
+
+            // Any other character: append
+            $line .= $char;
+        }
+
+        // CR found at end of stream
+        if ($crFound) {
+            throw new UnexpectedValueException("Unexpected end of headers");
+        }
+
+        return $line;
+    }
+
+    /**
+     * Split the stream into headers and body content.
+     *
+     * Returns an array containing two elements
+     *
+     * - The first is an array of headers
+     * - The second is a StreamInterface containing the body content
+     *
+     * @param StreamInterface $stream
+     * @return array
+     * @throws UnexpectedValueException For invalid headers.
+     */
+    protected static function splitStream(StreamInterface $stream)
+    {
+        $headers       = [];
+        $currentHeader = false;
+
+        while ($line = self::getLine($stream)) {
+            if (preg_match(';^(?P<name>[!#$%&\'*+.^_`\|~0-9a-zA-Z-]+):(?P<value>.*)$;', $line, $matches)) {
+                $currentHeader = $matches['name'];
+                if (! isset($headers[$currentHeader])) {
+                    $headers[$currentHeader] = [];
+                }
+                $headers[$currentHeader][] = ltrim($matches['value']);
+                continue;
+            }
+
+            if (! $currentHeader) {
+                throw new UnexpectedValueException('Invalid header detected');
+            }
+
+            if (! preg_match('#^[ \t]#', $line)) {
+                throw new UnexpectedValueException('Invalid header continuation');
+            }
+
+            // Append continuation to last header value found
+            $value = array_pop($headers[$currentHeader]);
+            $headers[$currentHeader][] = $value . ltrim($line);
+        }
+
+        // use RelativeStream to avoid copying initial stream into memory
+        return [$headers, new RelativeStream($stream, $stream->tell())];
+    }
+
+    /**
+     * Serialize headers to string values.
+     *
+     * @param array $headers
+     * @return string
+     */
+    protected static function serializeHeaders(array $headers)
+    {
+        $lines = [];
+        foreach ($headers as $header => $values) {
+            $normalized = self::filterHeader($header);
+            foreach ($values as $value) {
+                $lines[] = sprintf('%s: %s', $normalized, $value);
+            }
+        }
+
+        return implode("\r\n", $lines);
+    }
+
+    /**
+     * Filter a header name to wordcase
+     *
+     * @param string $header
+     * @return string
+     */
+    protected static function filterHeader($header)
+    {
+        $filtered = str_replace('-', ' ', $header);
+        $filtered = ucwords($filtered);
+        return str_replace(' ', '-', $filtered);
+    }
+}