@param WKBBuffer        $buffer
@param CoordinateSystem $cs

@return LineString
18574
private function readLineString(WKBBuffer $buffer, CoordinateSystem $cs) : LineString
    {
        $numPoints = $buffer->readUnsignedLong();

        $points = [];

        for ($i = 0; $i < $numPoints; $i++) {
            $points[] = $this->readPoint($buffer, $cs);
        }

        return new LineString($cs, ...$points);
    }
283068
private function _processHtmlCssMarker(&$pBuffer)
	{
		$this->_css = array_unique($this->_css);

		$skinPath = $this->_getSkinRelativePath();
		$cssTags = array();
		foreach ($this->_css as $css) {
			if (! filter_var($css, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) and strpos($css, '//') === false) {
				$filePath = $skinPath
							. self::APP_HTTP_CSS_DIR
							. DS
							. $css;
			} else {
				$filePath = $css;
			}

			$cssTags[] = '<link href="' . $filePath . '" rel="stylesheet" type="text/css">';
		}

		$pBuffer = str_replace(self::getCssMarker(), implode("\n", $cssTags) . "\n", $pBuffer);
		return $this;
	}
14383
private function readCircularStringText(WKTParser $parser, CoordinateSystem $cs) : CircularString
    {
        $points = $this->readMultiPoint($parser, $cs);

        return new CircularString($cs, ...$points);
    }
597502
function LineString(lineString) {
        crs(lineString);
        bbox(lineString);
        if (!requiredProperty(lineString, 'coordinates', 'array')) {
            positionArray(lineString.coordinates, 'Line', 1);
        }
    }
610939
private function readMultiPointText(WKTParser $parser, CoordinateSystem $cs) : MultiPoint
    {
        $points = $this->readMultiPoint($parser, $cs);

        return new MultiPoint($cs, ...$points);
    }
155631
private function readTINText(WKTParser $parser, CoordinateSystem $cs) : TIN
    {
        $parser->matchOpener();
        $patches = [];

        do {
            $patches[] = $this->readTriangleText($parser, $cs);
            $nextToken = $parser->getNextCloserOrComma();
        } while ($nextToken === ',');

        return new TIN($cs, ...$patches);
    }
70509
private function readMultiPolygon(WKBBuffer $buffer, CoordinateSystem $cs) : MultiPolygon
    {
        $numPolygons = $buffer->readUnsignedLong();
        $polygons = [];

        for ($i = 0; $i < $numPolygons; $i++) {
            $polygons[] = $this->readGeometry($buffer, $cs->SRID());
        }

        return new MultiPolygon($cs, ...$polygons);
    }
446716
protected static function translateFileSep(&$buffer, $pos)
    {
        if ($buffer{$pos} == '/' || $buffer{$pos} == '\\') {
            $buffer{$pos} = DIRECTORY_SEPARATOR;

            return true;
        }

        return false;
    }
1285486
private function readMultiLineString(WKTParser $parser, CoordinateSystem $cs) : array
    {
        $parser->matchOpener();
        $lineStrings = [];

        do {
            $lineStrings[] = $this->readLineStringText($parser, $cs);
            $nextToken = $parser->getNextCloserOrComma();
        } while ($nextToken === ',');

        return $lineStrings;
    }
1332430
private function readCompoundCurve(WKBBuffer $buffer, CoordinateSystem $cs) : CompoundCurve
    {
        $numCurves = $buffer->readUnsignedLong();
        $curves = [];

        for ($i = 0; $i < $numCurves; $i++) {
            $curves[] = $this->readGeometry($buffer, $cs->SRID());
        }

        return new CompoundCurve($cs, ...$curves);
    }
778950
private function readPolygonText(WKTParser $parser, CoordinateSystem $cs) : Polygon
    {
        $rings = $this->readMultiLineString($parser, $cs);

        return new Polygon($cs, ...$rings);
    }
329535
public static function deconstructCSP($cspString)
    {
        $csp = [];

        $directivesAndSources = explode(';', $cspString);

        foreach ($directivesAndSources as $directiveAndSources)
        {
            $directiveAndSources = ltrim($directiveAndSources);

            $list = explode(' ', $directiveAndSources, 2);

            $directive = strtolower($list[0]);

            if (isset($csp[$directive]))
            {
                continue;
            }

            if (isset($list[1]) and trim($list[1]) !== '')
            {
                $sourcesString = $list[1];

                $sources = explode(' ', $sourcesString);

                self::removeEmptySources($sources);
            }
            else
            {
                $sources = true;
            }

            $csp[$directive] = $sources;
        }

        return $csp;
    }
224589
private function readPoint(WKBBuffer $buffer, CoordinateSystem $cs) : Point
    {
        $coords = $buffer->readDoubles($cs->coordinateDimension());

        return new Point($cs, ...$coords);
    }
149454
public static String csv(String... msgs) {
		StringBuffer buf = new StringBuffer();
		for (String msg : msgs) {
			buf.append(msg);
			buf.append("; ");
		}
		return buf.toString();
	}
484589
public function output($buffer) {
        if (!$buffer && !$this->__result) {
            return '';
        }

        $out = '';
        // Always include the output generated by the expression first
        if ($buffer) {
            $out .= Garp_Cli::lineOut($buffer, null, true, false);
        }

        // And follow-up with the populated result, if any
        if ($this->__result) {
            // Try to format as user-friendly as possible
            $isObjWithToArray = is_object($this->__result) &&
                method_exists($this->__result, 'toArray');
            $this->__result = $isObjWithToArray ? $this->__result->toArray() : $this->__result;
            $this->__result = var_export($this->__result, true);
            $out .= Garp_Cli::lineOut($this->__result, Garp_Cli::BLUE, true, false);
        }

        return $out;
    }
287371
private function readGeometryCollectionText(WKTParser $parser, CoordinateSystem $cs) : GeometryCollection
    {
        $parser->matchOpener();
        $geometries = [];

        do {
            $geometries[] = $this->readGeometry($parser, $cs->SRID());
            $nextToken = $parser->getNextCloserOrComma();
        } while ($nextToken === ',');

        return new GeometryCollection($cs, ...$geometries);
    }
656334
public function returnBuffer($buffer = null)
    {
        if ($this->isBufferReturned)
        {
            return $buffer;
        }

        $this->apply($this->applyOnOutput);

        if (ob_get_level() and ! empty($this->errorString))
        {
            # prepend any errors to the buffer string (any errors that were
            # echoed will have been lost during an ob_start callback)
            $buffer = $this->errorString . $buffer;
        }

        # if we were called as part of ob_start, make note of this
        # (avoid doing redundent work if called again)
        $this->isBufferReturned = true;

        return $buffer;
    }