diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b9991e5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.idea/
+
+/vendor/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..60638d7
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,24 @@
+language: php
+
+sudo: false
+
+cache:
+ directories:
+ - $HOME/.composer/cache
+
+php:
+ - 7.0
+ - 7.1
+ - 7.2
+
+before_install:
+ - travis_retry composer self-update
+
+install:
+ - travis_retry composer update --no-interaction
+
+script:
+ - vendor/bin/phpunit --coverage-clover=coverage.xml
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bf0b1b5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# Pure PHP RRDtool file reader
+
+> Because on windows php ext-rrd can not read rrd files created on unix.
+
+**Only meant to export data out of rrd file. Not support for consolidation function etc**
+
+Original repository: http://javascriptrrd.sourceforge.net/
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..3a7484f
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,28 @@
+{
+ "name": "aldas/rrd-php-reader",
+ "description": "read rrd files purely using php",
+ "type": "library",
+ "license": "MIT",
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "RrdPhpReader\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
+ }
+ },
+ "scripts": {
+ "test": "vendor/bin/phpunit",
+ "test-unit": "vendor/bin/phpunit --testsuite 'unit-tests'",
+ "test-ci": "vendor/bin/phpunit --coverage-clover report/coverage.xml",
+ "test-coverage": "vendor/bin/phpunit --coverage-html report/html"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..661528d
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1474 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "496d5592906d476e5ff1367d87cb2482",
+ "packages": [],
+ "packages-dev": [
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2017-07-22T11:58:36+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
+ "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^4.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ },
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "time": "2017-10-19T19:58:43+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0",
+ "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "phar-io/version": "^1.0.1",
+ "php": "^5.6 || ^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "time": "2017-03-05T18:14:27+00:00"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df",
+ "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Library for handling version information and constraints",
+ "time": "2017-03-05T17:38:23+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "time": "2017-09-11T18:02:19+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "4.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "doctrine/instantiator": "~1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2017-11-30T07:14:17+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "time": "2017-07-14T14:27:02+00:00"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "1.7.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401",
+ "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ],
+ "time": "2018-02-19T10:16:54+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "6.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f8ca4b604baf23dab89d87773c28cc07405189ba",
+ "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.1",
+ "phpunit/php-file-iterator": "^1.4.2",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-token-stream": "^3.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0.1",
+ "sebastian/environment": "^3.0",
+ "sebastian/version": "^2.0.1",
+ "theseer/tokenizer": "^1.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "suggest": {
+ "ext-xdebug": "^2.6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "time": "2018-02-02T07:01:41+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2017-11-27T13:52:08+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2015-06-21T13:50:34+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2018-02-01T13:07:23+00:00"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2018-02-01T13:16:43+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "7.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9",
+ "reference": "e2f8aa21bc54b6ba218bdd4f9e0dac1e9bc3b4e9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "^1.6.1",
+ "phar-io/manifest": "^1.0.1",
+ "phar-io/version": "^1.0",
+ "php": "^7.1",
+ "phpspec/prophecy": "^1.7",
+ "phpunit/php-code-coverage": "^6.0",
+ "phpunit/php-file-iterator": "^1.4.3",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-timer": "^2.0",
+ "phpunit/phpunit-mock-objects": "^6.0",
+ "sebastian/comparator": "^2.1",
+ "sebastian/diff": "^3.0",
+ "sebastian/environment": "^3.1",
+ "sebastian/exporter": "^3.1",
+ "sebastian/global-state": "^2.0",
+ "sebastian/object-enumerator": "^3.0.3",
+ "sebastian/resource-operations": "^1.0",
+ "sebastian/version": "^2.0.1"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "^2.0"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2018-02-26T07:03:12+00:00"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "6.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "e3249dedc2d99259ccae6affbc2684eac37c2e53"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/e3249dedc2d99259ccae6affbc2684eac37c2e53",
+ "reference": "e3249dedc2d99259ccae6affbc2684eac37c2e53",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.5",
+ "php": "^7.1",
+ "phpunit/php-text-template": "^1.2.1",
+ "sebastian/exporter": "^3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2018-02-15T05:27:38+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "time": "2017-03-04T06:30:41+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "2.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9",
+ "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/diff": "^2.0 || ^3.0",
+ "sebastian/exporter": "^3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2018-02-01T13:46:46+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8",
+ "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0",
+ "symfony/process": "^2 || ^3.3 || ^4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "time": "2018-02-01T13:45:15+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2017-07-01T08:51:00+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
+ "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2017-04-03T13:19:02+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "time": "2017-04-27T15:39:26+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "sebastian/object-reflector": "^1.1.1",
+ "sebastian/recursion-context": "^3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "time": "2017-08-03T12:35:26+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "773f97c67f28de00d397be301821b06708fca0be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
+ "reference": "773f97c67f28de00d397be301821b06708fca0be",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "time": "2017-03-29T09:07:27+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "time": "2017-03-03T06:23:57+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "time": "2015-07-28T20:34:47+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2016-10-03T07:35:21+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "time": "2017-04-07T12:08:54+00:00"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "time": "2018-01-29T19:49:41+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": "^7.0"
+ },
+ "platform-dev": []
+}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..c19e5bd
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,25 @@
+
+
+
+
+ ./tests
+
+
+
+
+
+ src
+
+
+
diff --git a/src/Exception/InvalidRrdException.php b/src/Exception/InvalidRrdException.php
new file mode 100644
index 0000000..c528262
--- /dev/null
+++ b/src/Exception/InvalidRrdException.php
@@ -0,0 +1,9 @@
+rrdData = $rrdData;
+ $this->rra_ptr_idx = $rra_ptr_idx;
+ $this->rra_info = $rra_info;
+ $this->header_size = $header_size;
+ $this->prev_row_cnts = $prev_row_cnts;
+ $this->ds_cnt = $ds_cnt;
+
+
+ $this->row_cnt = $rra_info->getNrRows();
+
+ $this->row_size = $ds_cnt * 8;
+
+ $this->base_rrd_db_idx = $header_size + $prev_row_cnts * $this->row_size;
+
+ // get imediately, since it will be needed often
+ $this->cur_row = $rrdData->getLongAt($rra_ptr_idx);
+ }
+
+ private function calc_idx(int $row_idx, int $ds_idx)
+ {
+ if (($row_idx >= 0) && ($row_idx < $this->row_cnt)) {
+ if (($ds_idx >= 0) && ($ds_idx < $this->ds_cnt)) {
+ // it is round robin, starting from cur_row+1
+ $real_row_idx = $row_idx + $this->cur_row + 1;
+ if ($real_row_idx >= $this->row_cnt) {
+ $real_row_idx -= $this->row_cnt;
+ }
+ return $this->row_size * $real_row_idx + $ds_idx * 8;
+ }
+ throw new RrdRangeException("DS idx ({$row_idx}) out of range [0-{$this->ds_cnt}).");
+ }
+ throw new RrdRangeException("Row idx ({$row_idx}) out of range [0-{$this->row_cnt}).");
+ }
+
+
+ public function getIdx(): int
+ {
+ return $this->rraInfo->getIdx();
+ }
+
+ public function getNrRows(): int
+ {
+ return $this->row_cnt;
+ }
+
+ public function getNrDSs(): int
+ {
+ return $this->ds_cnt;
+ }
+
+ public function getStep(): int
+ {
+ return $this->rraInfo->getStep();
+ }
+
+ public function getCFName(): string
+ {
+ return $this->rraInfo->getCFName();
+ }
+
+ public function getEl($row_idx, $ds_idx): float
+ {
+ return $this->rrdData->getDoubleAt($this->base_rrd_db_idx + $this->calc_idx($row_idx, $ds_idx));
+ }
+}
\ No newline at end of file
diff --git a/src/Rra/RraInfo.php b/src/Rra/RraInfo.php
new file mode 100644
index 0000000..0446545
--- /dev/null
+++ b/src/Rra/RraInfo.php
@@ -0,0 +1,80 @@
+rrd_data = $rrd_data;
+ $this->rra_def_idx = $rra_def_idx;
+ $this->int_align = $int_align;
+ $this->row_cnt = $row_cnt;
+ $this->pdp_step = $pdp_step;
+ $this->my_idx = $my_idx;
+
+ $this->rra_pdp_cnt_idx = $rra_def_idx + ceil(20 / $int_align) * $int_align + $int_align;
+ }
+
+ public function getIdx(): int
+ {
+ return $this->my_idx;
+ }
+
+ /**
+ * Get number of rows
+ *
+ * @return int
+ */
+ public function getNrRows(): int
+ {
+ return $this->row_cnt;
+ }
+
+ /**
+ * Get number of slots used for consolidation
+ *
+ * @return int
+ */
+ public function getPdpPerRow(): int
+ {
+ return $this->rrd_data->getLongAt($this->rra_pdp_cnt_idx);
+ }
+
+ /**
+ * Get RRA step (expressed in seconds)
+ *
+ * @return int
+ */
+ public function getStep(): int
+ {
+ return $this->pdp_step * $this->getPdpPerRow();
+ }
+
+ /**
+ * Get consolidation function name
+ *
+ * @return string
+ */
+ public function getCFName(): string
+ {
+ return $this->rrd_data->getCStringAt($this->rra_def_idx, 20);
+ }
+
+}
\ No newline at end of file
diff --git a/src/RrdData.php b/src/RrdData.php
new file mode 100644
index 0000000..7d5656e
--- /dev/null
+++ b/src/RrdData.php
@@ -0,0 +1,117 @@
+data = $data;
+ $this->length = \strlen($data);
+ }
+
+ public function getLength(): int
+ {
+ return $this->length;
+ }
+
+ public function setSwitchEndian(bool $switchEndian)
+ {
+ $this->switch_endian = $switchEndian;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isSwitchEndian(): bool
+ {
+ return $this->switch_endian;
+ }
+
+ /**
+ * Return a 8 bit unsigned integer at offset idx
+ *
+ * @param int $idx
+ * @return int
+ */
+ public function getByteAt(int $idx): int
+ {
+ return (int)$this->data[$idx];
+ }
+
+ private function getEndianByteAt(int $iOffset, int $width, int $delta = 0)
+ {
+ if ($this->switch_endian) {
+ $index = $iOffset + $width - $delta - 1;
+ } else {
+ $index = $iOffset + $width;
+ }
+ return $this->getByteAt($index);
+ }
+
+ /**
+ * Return a 32 bit unsigned integer at offset idx
+ *
+ * @param int $idx
+ * @return int
+ */
+ public function getLongAt(int $idx): int
+ {
+ $raw = substr($this->data, $idx, 4);
+ $format = 'V'; // unsigned long (always 32 bit, little endian byte order)
+ if ($this->switch_endian) {
+ $format = 'N'; // unsigned long (always 32 bit, big endian byte order)
+ }
+ $unpack = unpack($format, $raw);
+ return $unpack[1];
+ }
+
+ /**
+ * Return a double float at offset idx
+ *
+ * @param int $idx
+ * @return float
+ */
+ public function getDoubleAt(int $idx): float
+ {
+ $raw = substr($this->data, $idx, 8);
+ $format = 'e'; // double (machine dependent size, little endian byte order)
+ if ($this->switch_endian) {
+ $format = 'E'; // double (machine dependent size, big endian byte order)
+ }
+ $unpack = unpack($format, $raw);
+ return $unpack[1];
+ }
+
+ /**
+ * Return a string of at most maxsize characters that was 0-terminated in the source
+ *
+ * @param int $idx
+ * @param int $maxSize
+ * @return string
+ */
+ public function getCStringAt(int $idx, int $maxSize): string
+ {
+ $raw = substr($this->data, $idx, $maxSize);
+ $unpack = unpack('A*', $raw);
+ return $unpack[1];
+ }
+
+}
\ No newline at end of file
diff --git a/src/RrdDs.php b/src/RrdDs.php
new file mode 100644
index 0000000..551860a
--- /dev/null
+++ b/src/RrdDs.php
@@ -0,0 +1,54 @@
+rrdData = $rrdData;
+ $this->idx = $idx;
+ $this->myIdx = $myIdx;
+ }
+
+ public function getIdx(): int
+ {
+ return $this->myIdx;
+ }
+
+ public function getName(): string
+ {
+ return $this->rrdData->getCStringAt($this->idx, 20);
+ }
+
+ public function getType(): string
+ {
+ return $this->rrdData->getCStringAt($this->idx + 20, 20);
+ }
+
+ public function getMin(): float
+ {
+ return $this->rrdData->getDoubleAt($this->idx + 48);
+ }
+
+ public function getMax(): float
+ {
+ return $this->rrdData->getDoubleAt($this->idx + 56);
+ }
+}
\ No newline at end of file
diff --git a/src/RrdFile.php b/src/RrdFile.php
new file mode 100644
index 0000000..63500d5
--- /dev/null
+++ b/src/RrdFile.php
@@ -0,0 +1,79 @@
+rrdData = $rrdData;
+ $this->header = new RrdHeader($rrdData);
+ }
+
+ public function getHeader(): RrdHeader
+ {
+ return $this->header;
+ }
+
+ public function getMinStep()
+ {
+ return $this->header->getMinStep();
+ }
+
+ public function getLastUpdate()
+ {
+ return $this->header->getLastUpdate();
+ }
+
+ public function getNrDSs()
+ {
+ return $this->header->getNrDSs();
+ }
+
+ public function getDS($ds)
+ {
+ if (\is_string($ds)) {
+ return $this->header->getDSbyName($ds);
+ }
+ return $this->header->getDSbyIdx($ds);
+ }
+
+ public function getNrRRAs()
+ {
+ return $this->header->getNrRRAs();
+ }
+
+ public function getRRAInfo(int $idx): RraInfo
+ {
+ return $this->header->getRRAInfo($idx);
+ }
+
+ public function getRRA(int $idx): Rra
+ {
+ $rra_info = $this->header->getRRAInfo($idx);
+ return new Rra(
+ $this->rrdData,
+ $this->header->rra_ptr_idx + $idx * $this->header->rra_ptr_el_size,
+ $rra_info,
+ $this->header->header_size,
+ $this->header->rra_def_row_cnt_sums[$idx],
+ $this->header->getNrDSs()
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/RrdHeader.php b/src/RrdHeader.php
new file mode 100644
index 0000000..6cbb103
--- /dev/null
+++ b/src/RrdHeader.php
@@ -0,0 +1,412 @@
+rrdData = $rrdData;
+
+ $this->initialize();
+ $this->calculateIndexes();
+ $this->loadRowCounts();
+ }
+
+ /**
+ * @throws InvalidRrdException
+ */
+ private function initialize()
+ {
+ $length = $this->rrdData->getLength();
+ if ($length < 1) {
+ throw new InvalidRrdException('Empty file.');
+ }
+ if ($length < 16) {
+ throw new InvalidRrdException('File too short.');
+ }
+ $magicId = $this->rrdData->getCStringAt(0, 4);
+ if ($magicId !== 'RRD') {
+ throw new InvalidRrdException('Wrong magic id.');
+ }
+
+ $this->rrd_version = $this->rrdData->getCStringAt(4, 5);
+ if (!\in_array($this->rrd_version, ['0003', '0004', '0001'], true)) {
+ throw new InvalidRrdException("Unsupported RRD version {$this->rrd_version}.");
+ }
+
+ $this->float_width = 8;
+ if ($this->rrdData->getLongAt(12) === 0) {
+ // not a double here... likely 64 bit
+ $this->float_align = 8;
+ if (!($this->rrdData->getDoubleAt(16) === 8.642135e+130)) { // TODO check what in PHP it would be
+ // uhm... wrong endian?
+ $this->rrdData->setSwitchEndian(true);
+ }
+ if ($this->rrdData->getDoubleAt(16) === 8.642135e+130) {// TODO check what in PHP it would be
+ // now, is it all 64bit or only float 64 bit?
+ if ($this->rrdData->getLongAt(28) === 0) {
+ // true 64 bit align
+ $this->int_align = 8;
+ $this->int_width = 8;
+ } else {
+ // integers are 32bit aligned
+ $this->int_align = 4;
+ $this->int_width = 4;
+ }
+ } else {
+ throw new InvalidRrdException('Magic float not found at 16.');
+ }
+ } else {
+ /// should be 32 bit alignment
+ if (!($this->rrdData->getDoubleAt(12) === 8.642135e+130)) {// TODO check what in PHP it would be
+ // uhm... wrong endian?
+ $this->rrdData->setSwitchEndian(true);
+ }
+ if ($this->rrdData->getDoubleAt(12) === 8.642135e+130) {// TODO check what in PHP it would be
+ $this->float_align = 4;
+ $this->int_align = 4;
+ $this->int_width = 4;
+ } else {
+ throw new InvalidRrdException('Magic float not found at 12.');
+ }
+ }
+ $this->unival_width = $this->float_width;
+ $this->unival_align = $this->float_align;
+
+ // process the header here, since I need it for validation
+
+ // char magic[4], char version[5], double magic_float
+
+ // long ds_cnt, long rra_cnt, long pdp_step, unival par[10]
+ $this->ds_cnt_idx = (int)(ceil((4 + 5) / $this->float_align) * $this->float_align + $this->float_width);
+ $this->rra_cnt_idx = $this->ds_cnt_idx + $this->int_width;
+ $this->pdp_step_idx = $this->rra_cnt_idx + $this->int_width;
+
+ //always get only the low 32 bits, the high 32 on 64 bit archs should always be 0
+ $this->ds_cnt = $this->rrdData->getLongAt($this->ds_cnt_idx);
+ if ($this->ds_cnt < 1) {
+ throw new InvalidRrdException('ds count less than 1.');
+ }
+
+ $this->rra_cnt = $this->rrdData->getLongAt($this->rra_cnt_idx);
+ if ($this->ds_cnt < 1) {
+ throw new InvalidRrdException('rra count less than 1.');
+ }
+
+ $this->pdp_step = $this->rrdData->getLongAt($this->pdp_step_idx);
+ if ($this->pdp_step < 1) {
+ throw new InvalidRrdException('pdp step less than 1.');
+ }
+
+ // best guess, assuming no weird align problems
+ $this->top_header_size = (int)(ceil(($this->pdp_step_idx + $this->int_width) / $this->unival_align) * $this->unival_align + 10 * $this->unival_width);
+ $t = $this->rrdData->getLongAt($this->top_header_size);
+ if ($t === 0) {
+ throw new InvalidRrdException('Could not find first DS name.');
+ }
+ }
+
+ private function calculateIndexes()
+ {
+ $this->ds_def_idx = $this->top_header_size;
+ // char ds_nam[20], char dst[20], unival par[10]
+ $this->ds_el_size = (int)(ceil((20 + 20) / $this->unival_align) * $this->unival_align + 10 * $this->unival_width);
+
+ $this->rra_def_idx = $this->ds_def_idx + $this->ds_el_size * $this->ds_cnt;
+ // char cf_nam[20], uint row_cnt, uint pdp_cnt, unival par[10]
+ $this->row_cnt_idx = (int)(ceil(20 / $this->int_align) * $this->int_align);
+ $this->rra_def_el_size = (int)(ceil(($this->row_cnt_idx + 2 * $this->int_width) / $this->unival_align) * $this->unival_align + 10 * $this->unival_width);
+
+ $this->live_head_idx = $this->rra_def_idx + $this->rra_def_el_size * $this->rra_cnt;
+ // time_t last_up, int last_up_usec
+ $this->live_head_size = 2 * $this->int_width;
+
+ $this->pdp_prep_idx = $this->live_head_idx + $this->live_head_size;
+ // char last_ds[30], unival scratch[10]
+ $this->pdp_prep_el_size = (int)(ceil(30 / $this->unival_align) * $this->unival_align + 10 * $this->unival_width);
+
+ $this->cdp_prep_idx = $this->pdp_prep_idx + $this->pdp_prep_el_size * $this->ds_cnt;
+ // unival scratch[10]
+ $this->cdp_prep_el_size = 10 * $this->unival_width;
+
+ $this->rra_ptr_idx = $this->cdp_prep_idx + $this->cdp_prep_el_size * $this->ds_cnt * $this->rra_cnt;
+ // uint cur_row
+ $this->rra_ptr_el_size = 1 * $this->int_width;
+
+ $this->header_size = $this->rra_ptr_idx + $this->rra_ptr_el_size * $this->rra_cnt;
+ }
+
+ private function loadRowCounts()
+ {
+ $this->rra_def_row_cnts = [];
+ $this->rra_def_row_cnt_sums = []; // how many rows before me
+
+ for ($i = 0; $i < $this->rra_cnt; $i++) {
+ $this->rra_def_row_cnts[$i] = $this->rrdData->getLongAt($this->rra_def_idx + $i * $this->rra_def_el_size + $this->row_cnt_idx);
+
+ if ($i === 0) {
+ $this->rra_def_row_cnt_sums[$i] = 0;
+ } else {
+ $this->rra_def_row_cnt_sums[$i] = $this->rra_def_row_cnt_sums[$i - 1] + $this->rra_def_row_cnts[$i - 1];
+ }
+ }
+ }
+
+ public function getMinStep(): int
+ {
+ return $this->pdp_step;
+ }
+
+ public function getLastUpdate(): int
+ {
+ return $this->rrdData->getLongAt($this->live_head_idx);
+ }
+
+ public function getNrDSs(): int
+ {
+ return $this->ds_cnt;
+ }
+
+ /**
+ * @return string[]
+ * @throws \RrdPhpReader\Exception\RrdRangeException
+ */
+ public function getDSNames(): array
+ {
+ $dsNames = [];
+ for ($idx = 0; $idx < $this->ds_cnt; $idx++) {
+ $dsNames[] = $this->getDSbyIdx($idx)->getName();
+ }
+
+ return $dsNames;
+ }
+
+ /**
+ * @param int $idx
+ * @return RrdDs
+ * @throws \RrdPhpReader\Exception\RrdRangeException
+ */
+ public function getDSbyIdx(int $idx): RrdDs
+ {
+ if (($idx >= 0) && ($idx < $this->ds_cnt)) {
+ return new RrdDs(
+ $this->rrdData,
+ $this->ds_def_idx + $this->ds_el_size * $idx,
+ $idx
+ );
+ }
+ throw new RrdRangeException("DS idx ({$idx}) out of range [0-{$this->ds_cnt}).");
+ }
+
+ /**
+ * @param string $name
+ * @return RrdDs
+ * @throws \RrdPhpReader\Exception\RrdRangeException
+ */
+ public function getDSbyName(string $name): RrdDs
+ {
+ for ($idx = 0; $idx < $this->ds_cnt; $idx++) {
+ $ds = $this->getDSbyIdx($idx);
+ $ds_name = $ds->getName();
+ if ($ds_name === $name) {
+ return $ds;
+ }
+ }
+ throw new RrdRangeException("DS name {$name} unknown.");
+ }
+
+ public function getNrRRAs(): int
+ {
+ return $this->rra_cnt;
+ }
+
+ /**
+ * @param $idx
+ * @return RraInfo
+ * @throws \RrdPhpReader\Exception\RrdRangeException
+ */
+ public function getRRAInfo(int $idx): RraInfo
+ {
+ if (($idx >= 0) && ($idx < $this->rra_cnt)) {
+ $rra_def_idx = $this->rra_def_idx + $idx * $this->rra_def_el_size;
+ return new RraInfo(
+ $this->rrdData,
+ $rra_def_idx,
+ $this->int_align,
+ $this->rra_def_row_cnts[$idx],
+ $this->pdp_step,
+ $idx
+ );
+ }
+ throw new RrdRangeException("RRA idx ({$idx}) out of range [0-{$this->rra_cnt}).");
+ }
+
+}
\ No newline at end of file
diff --git a/tests/FileUtils.php b/tests/FileUtils.php
new file mode 100644
index 0000000..828c6c3
--- /dev/null
+++ b/tests/FileUtils.php
@@ -0,0 +1,14 @@
+assertEquals(2, $rrdFile->getNrDSs());
+ $this->assertEquals(
+ ['value', 'extra_value'],
+ $rrdFile->getHeader()->getDSNames()
+ );
+ }
+
+ public function testReadWindows()
+ {
+ $file = new RrdData(FileUtils::getContents('rrd_win_64bit.rrd'));
+ $rrdFile = new RrdFile($file);
+
+ $this->assertEquals(1, $rrdFile->getNrDSs());
+ $this->assertEquals(
+ ['value'],
+ $rrdFile->getHeader()->getDSNames()
+ );
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ * @expectedExceptionMessage Help
+ */
+ public function testShouldThrowExceptionForHugeData()
+ {
+ throw new \RuntimeException('Help');
+ }
+}
\ No newline at end of file
diff --git a/tests/data/rrd_linux_x86_64.rrd b/tests/data/rrd_linux_x86_64.rrd
new file mode 100644
index 0000000..f514acc
Binary files /dev/null and b/tests/data/rrd_linux_x86_64.rrd differ
diff --git a/tests/data/rrd_linux_x86_64_dump.xml b/tests/data/rrd_linux_x86_64_dump.xml
new file mode 100644
index 0000000..27b1202
--- /dev/null
+++ b/tests/data/rrd_linux_x86_64_dump.xml
@@ -0,0 +1,630 @@
+
+
+
+
+ 0003
+ 1
+ 1521044275
+
+
+ value
+ GAUGE
+ 10
+ NaN
+ NaN
+
+
+ 3599
+ 0.0000000000e+00
+ 0
+
+
+
+ extra_value
+ GAUGE
+ 10
+ NaN
+ NaN
+
+
+ 0.5
+ 0.0000000000e+00
+ 0
+
+
+
+
+ AVERAGE
+ 1
+
+
+ 5.0000000000e-01
+
+
+
+ 3.5990000000e+03
+ 0.0000000000e+00
+ NaN
+ 0
+
+
+ 5.0000000000e-01
+ 0.0000000000e+00
+ NaN
+ 0
+
+
+
+ 3.5700000000e+031.5000000000e+01
+ 3.5710000000e+031.4500000000e+01
+ 3.5720000000e+031.4000000000e+01
+ 3.5730000000e+031.3500000000e+01
+ 3.5740000000e+031.3000000000e+01
+ 3.5750000000e+031.2500000000e+01
+ 3.5760000000e+031.2000000000e+01
+ 3.5770000000e+031.1500000000e+01
+ 3.5780000000e+031.1000000000e+01
+ 3.5790000000e+031.0500000000e+01
+ 3.5800000000e+031.0000000000e+01
+ 3.5810000000e+039.5000000000e+00
+ 3.5820000000e+039.0000000000e+00
+ 3.5830000000e+038.5000000000e+00
+ 3.5840000000e+038.0000000000e+00
+ 3.5850000000e+037.5000000000e+00
+ 3.5860000000e+037.0000000000e+00
+ 3.5870000000e+036.5000000000e+00
+ 3.5880000000e+036.0000000000e+00
+ 3.5890000000e+035.5000000000e+00
+ 3.5900000000e+035.0000000000e+00
+ 3.5910000000e+034.5000000000e+00
+ 3.5920000000e+034.0000000000e+00
+ 3.5930000000e+033.5000000000e+00
+ 3.5940000000e+033.0000000000e+00
+ 3.5950000000e+032.5000000000e+00
+ 3.5960000000e+032.0000000000e+00
+ 3.5970000000e+031.5000000000e+00
+ 3.5980000000e+031.0000000000e+00
+ 3.5990000000e+035.0000000000e-01
+
+
+
+ MIN
+ 1
+
+
+ 5.0000000000e-01
+
+
+
+ 3.5990000000e+03
+ 0.0000000000e+00
+ NaN
+ 0
+
+
+ 5.0000000000e-01
+ 0.0000000000e+00
+ NaN
+ 0
+
+
+
+ 3.5700000000e+031.5000000000e+01
+ 3.5710000000e+031.4500000000e+01
+ 3.5720000000e+031.4000000000e+01
+ 3.5730000000e+031.3500000000e+01
+ 3.5740000000e+031.3000000000e+01
+ 3.5750000000e+031.2500000000e+01
+ 3.5760000000e+031.2000000000e+01
+ 3.5770000000e+031.1500000000e+01
+ 3.5780000000e+031.1000000000e+01
+ 3.5790000000e+031.0500000000e+01
+ 3.5800000000e+031.0000000000e+01
+ 3.5810000000e+039.5000000000e+00
+ 3.5820000000e+039.0000000000e+00
+ 3.5830000000e+038.5000000000e+00
+ 3.5840000000e+038.0000000000e+00
+ 3.5850000000e+037.5000000000e+00
+ 3.5860000000e+037.0000000000e+00
+ 3.5870000000e+036.5000000000e+00
+ 3.5880000000e+036.0000000000e+00
+ 3.5890000000e+035.5000000000e+00
+ 3.5900000000e+035.0000000000e+00
+ 3.5910000000e+034.5000000000e+00
+ 3.5920000000e+034.0000000000e+00
+ 3.5930000000e+033.5000000000e+00
+ 3.5940000000e+033.0000000000e+00
+ 3.5950000000e+032.5000000000e+00
+ 3.5960000000e+032.0000000000e+00
+ 3.5970000000e+031.5000000000e+00
+ 3.5980000000e+031.0000000000e+00
+ 3.5990000000e+035.0000000000e-01
+
+
+
+ MAX
+ 1
+
+
+ 5.0000000000e-01
+
+
+
+ 3.5990000000e+03
+ 0.0000000000e+00
+ NaN
+ 0
+
+
+ 5.0000000000e-01
+ 0.0000000000e+00
+ NaN
+ 0
+
+
+
+ 3.5700000000e+031.5000000000e+01
+ 3.5710000000e+031.4500000000e+01
+ 3.5720000000e+031.4000000000e+01
+ 3.5730000000e+031.3500000000e+01
+ 3.5740000000e+031.3000000000e+01
+ 3.5750000000e+031.2500000000e+01
+ 3.5760000000e+031.2000000000e+01
+ 3.5770000000e+031.1500000000e+01
+ 3.5780000000e+031.1000000000e+01
+ 3.5790000000e+031.0500000000e+01
+ 3.5800000000e+031.0000000000e+01
+ 3.5810000000e+039.5000000000e+00
+ 3.5820000000e+039.0000000000e+00
+ 3.5830000000e+038.5000000000e+00
+ 3.5840000000e+038.0000000000e+00
+ 3.5850000000e+037.5000000000e+00
+ 3.5860000000e+037.0000000000e+00
+ 3.5870000000e+036.5000000000e+00
+ 3.5880000000e+036.0000000000e+00
+ 3.5890000000e+035.5000000000e+00
+ 3.5900000000e+035.0000000000e+00
+ 3.5910000000e+034.5000000000e+00
+ 3.5920000000e+034.0000000000e+00
+ 3.5930000000e+033.5000000000e+00
+ 3.5940000000e+033.0000000000e+00
+ 3.5950000000e+032.5000000000e+00
+ 3.5960000000e+032.0000000000e+00
+ 3.5970000000e+031.5000000000e+00
+ 3.5980000000e+031.0000000000e+00
+ 3.5990000000e+035.0000000000e-01
+
+
+
+ AVERAGE
+ 5
+
+
+ 5.0000000000e-01
+
+
+
+ 3.5970000000e+03
+ 3.5990000000e+03
+ 0.0000000000e+00
+ 0
+
+
+ 1.5000000000e+00
+ 5.0000000000e-01
+ 0.0000000000e+00
+ 0
+
+
+
+ 3.0020000000e+032.9900000000e+02
+ 3.0070000000e+032.9650000000e+02
+ 3.0120000000e+032.9400000000e+02
+ 3.0170000000e+032.9150000000e+02
+ 3.0220000000e+032.8900000000e+02
+ 3.0270000000e+032.8650000000e+02
+ 3.0320000000e+032.8400000000e+02
+ 3.0370000000e+032.8150000000e+02
+ 3.0420000000e+032.7900000000e+02
+ 3.0470000000e+032.7650000000e+02
+ 3.0520000000e+032.7400000000e+02
+ 3.0570000000e+032.7150000000e+02
+ 3.0620000000e+032.6900000000e+02
+ 3.0670000000e+032.6650000000e+02
+ 3.0720000000e+032.6400000000e+02
+ 3.0770000000e+032.6150000000e+02
+ 3.0820000000e+032.5900000000e+02
+ 3.0870000000e+032.5650000000e+02
+ 3.0920000000e+032.5400000000e+02
+ 3.0970000000e+032.5150000000e+02
+ 3.1020000000e+032.4900000000e+02
+ 3.1070000000e+032.4650000000e+02
+ 3.1120000000e+032.4400000000e+02
+ 3.1170000000e+032.4150000000e+02
+ 3.1220000000e+032.3900000000e+02
+ 3.1270000000e+032.3650000000e+02
+ 3.1320000000e+032.3400000000e+02
+ 3.1370000000e+032.3150000000e+02
+ 3.1420000000e+032.2900000000e+02
+ 3.1470000000e+032.2650000000e+02
+ 3.1520000000e+032.2400000000e+02
+ 3.1570000000e+032.2150000000e+02
+ 3.1620000000e+032.1900000000e+02
+ 3.1670000000e+032.1650000000e+02
+ 3.1720000000e+032.1400000000e+02
+ 3.1770000000e+032.1150000000e+02
+ 3.1820000000e+032.0900000000e+02
+ 3.1870000000e+032.0650000000e+02
+ 3.1920000000e+032.0400000000e+02
+ 3.1970000000e+032.0150000000e+02
+ 3.2020000000e+031.9900000000e+02
+ 3.2070000000e+031.9650000000e+02
+ 3.2120000000e+031.9400000000e+02
+ 3.2170000000e+031.9150000000e+02
+ 3.2220000000e+031.8900000000e+02
+ 3.2270000000e+031.8650000000e+02
+ 3.2320000000e+031.8400000000e+02
+ 3.2370000000e+031.8150000000e+02
+ 3.2420000000e+031.7900000000e+02
+ 3.2470000000e+031.7650000000e+02
+ 3.2520000000e+031.7400000000e+02
+ 3.2570000000e+031.7150000000e+02
+ 3.2620000000e+031.6900000000e+02
+ 3.2670000000e+031.6650000000e+02
+ 3.2720000000e+031.6400000000e+02
+ 3.2770000000e+031.6150000000e+02
+ 3.2820000000e+031.5900000000e+02
+ 3.2870000000e+031.5650000000e+02
+ 3.2920000000e+031.5400000000e+02
+ 3.2970000000e+031.5150000000e+02
+ 3.3020000000e+031.4900000000e+02
+ 3.3070000000e+031.4650000000e+02
+ 3.3120000000e+031.4400000000e+02
+ 3.3170000000e+031.4150000000e+02
+ 3.3220000000e+031.3900000000e+02
+ 3.3270000000e+031.3650000000e+02
+ 3.3320000000e+031.3400000000e+02
+ 3.3370000000e+031.3150000000e+02
+ 3.3420000000e+031.2900000000e+02
+ 3.3470000000e+031.2650000000e+02
+ 3.3520000000e+031.2400000000e+02
+ 3.3570000000e+031.2150000000e+02
+ 3.3620000000e+031.1900000000e+02
+ 3.3670000000e+031.1650000000e+02
+ 3.3720000000e+031.1400000000e+02
+ 3.3770000000e+031.1150000000e+02
+ 3.3820000000e+031.0900000000e+02
+ 3.3870000000e+031.0650000000e+02
+ 3.3920000000e+031.0400000000e+02
+ 3.3970000000e+031.0150000000e+02
+ 3.4020000000e+039.9000000000e+01
+ 3.4070000000e+039.6500000000e+01
+ 3.4120000000e+039.4000000000e+01
+ 3.4170000000e+039.1500000000e+01
+ 3.4220000000e+038.9000000000e+01
+ 3.4270000000e+038.6500000000e+01
+ 3.4320000000e+038.4000000000e+01
+ 3.4370000000e+038.1500000000e+01
+ 3.4420000000e+037.9000000000e+01
+ 3.4470000000e+037.6500000000e+01
+ 3.4520000000e+037.4000000000e+01
+ 3.4570000000e+037.1500000000e+01
+ 3.4620000000e+036.9000000000e+01
+ 3.4670000000e+036.6500000000e+01
+ 3.4720000000e+036.4000000000e+01
+ 3.4770000000e+036.1500000000e+01
+ 3.4820000000e+035.9000000000e+01
+ 3.4870000000e+035.6500000000e+01
+ 3.4920000000e+035.4000000000e+01
+ 3.4970000000e+035.1500000000e+01
+ 3.5020000000e+034.9000000000e+01
+ 3.5070000000e+034.6500000000e+01
+ 3.5120000000e+034.4000000000e+01
+ 3.5170000000e+034.1500000000e+01
+ 3.5220000000e+033.9000000000e+01
+ 3.5270000000e+033.6500000000e+01
+ 3.5320000000e+033.4000000000e+01
+ 3.5370000000e+033.1500000000e+01
+ 3.5420000000e+032.9000000000e+01
+ 3.5470000000e+032.6500000000e+01
+ 3.5520000000e+032.4000000000e+01
+ 3.5570000000e+032.1500000000e+01
+ 3.5620000000e+031.9000000000e+01
+ 3.5670000000e+031.6500000000e+01
+ 3.5720000000e+031.4000000000e+01
+ 3.5770000000e+031.1500000000e+01
+ 3.5820000000e+039.0000000000e+00
+ 3.5870000000e+036.5000000000e+00
+ 3.5920000000e+034.0000000000e+00
+ 3.5970000000e+031.5000000000e+00
+
+
+
+ MIN
+ 5
+
+
+ 5.0000000000e-01
+
+
+
+ 3.5950000000e+03
+ 3.5990000000e+03
+ inf
+ 0
+
+
+ 5.0000000000e-01
+ 5.0000000000e-01
+ inf
+ 0
+
+
+
+ 3.0000000000e+032.9800000000e+02
+ 3.0050000000e+032.9550000000e+02
+ 3.0100000000e+032.9300000000e+02
+ 3.0150000000e+032.9050000000e+02
+ 3.0200000000e+032.8800000000e+02
+ 3.0250000000e+032.8550000000e+02
+ 3.0300000000e+032.8300000000e+02
+ 3.0350000000e+032.8050000000e+02
+ 3.0400000000e+032.7800000000e+02
+ 3.0450000000e+032.7550000000e+02
+ 3.0500000000e+032.7300000000e+02
+ 3.0550000000e+032.7050000000e+02
+ 3.0600000000e+032.6800000000e+02
+ 3.0650000000e+032.6550000000e+02
+ 3.0700000000e+032.6300000000e+02
+ 3.0750000000e+032.6050000000e+02
+ 3.0800000000e+032.5800000000e+02
+ 3.0850000000e+032.5550000000e+02
+ 3.0900000000e+032.5300000000e+02
+ 3.0950000000e+032.5050000000e+02
+ 3.1000000000e+032.4800000000e+02
+ 3.1050000000e+032.4550000000e+02
+ 3.1100000000e+032.4300000000e+02
+ 3.1150000000e+032.4050000000e+02
+ 3.1200000000e+032.3800000000e+02
+ 3.1250000000e+032.3550000000e+02
+ 3.1300000000e+032.3300000000e+02
+ 3.1350000000e+032.3050000000e+02
+ 3.1400000000e+032.2800000000e+02
+ 3.1450000000e+032.2550000000e+02
+ 3.1500000000e+032.2300000000e+02
+ 3.1550000000e+032.2050000000e+02
+ 3.1600000000e+032.1800000000e+02
+ 3.1650000000e+032.1550000000e+02
+ 3.1700000000e+032.1300000000e+02
+ 3.1750000000e+032.1050000000e+02
+ 3.1800000000e+032.0800000000e+02
+ 3.1850000000e+032.0550000000e+02
+ 3.1900000000e+032.0300000000e+02
+ 3.1950000000e+032.0050000000e+02
+ 3.2000000000e+031.9800000000e+02
+ 3.2050000000e+031.9550000000e+02
+ 3.2100000000e+031.9300000000e+02
+ 3.2150000000e+031.9050000000e+02
+ 3.2200000000e+031.8800000000e+02
+ 3.2250000000e+031.8550000000e+02
+ 3.2300000000e+031.8300000000e+02
+ 3.2350000000e+031.8050000000e+02
+ 3.2400000000e+031.7800000000e+02
+ 3.2450000000e+031.7550000000e+02
+ 3.2500000000e+031.7300000000e+02
+ 3.2550000000e+031.7050000000e+02
+ 3.2600000000e+031.6800000000e+02
+ 3.2650000000e+031.6550000000e+02
+ 3.2700000000e+031.6300000000e+02
+ 3.2750000000e+031.6050000000e+02
+ 3.2800000000e+031.5800000000e+02
+ 3.2850000000e+031.5550000000e+02
+ 3.2900000000e+031.5300000000e+02
+ 3.2950000000e+031.5050000000e+02
+ 3.3000000000e+031.4800000000e+02
+ 3.3050000000e+031.4550000000e+02
+ 3.3100000000e+031.4300000000e+02
+ 3.3150000000e+031.4050000000e+02
+ 3.3200000000e+031.3800000000e+02
+ 3.3250000000e+031.3550000000e+02
+ 3.3300000000e+031.3300000000e+02
+ 3.3350000000e+031.3050000000e+02
+ 3.3400000000e+031.2800000000e+02
+ 3.3450000000e+031.2550000000e+02
+ 3.3500000000e+031.2300000000e+02
+ 3.3550000000e+031.2050000000e+02
+ 3.3600000000e+031.1800000000e+02
+ 3.3650000000e+031.1550000000e+02
+ 3.3700000000e+031.1300000000e+02
+ 3.3750000000e+031.1050000000e+02
+ 3.3800000000e+031.0800000000e+02
+ 3.3850000000e+031.0550000000e+02
+ 3.3900000000e+031.0300000000e+02
+ 3.3950000000e+031.0050000000e+02
+ 3.4000000000e+039.8000000000e+01
+ 3.4050000000e+039.5500000000e+01
+ 3.4100000000e+039.3000000000e+01
+ 3.4150000000e+039.0500000000e+01
+ 3.4200000000e+038.8000000000e+01
+ 3.4250000000e+038.5500000000e+01
+ 3.4300000000e+038.3000000000e+01
+ 3.4350000000e+038.0500000000e+01
+ 3.4400000000e+037.8000000000e+01
+ 3.4450000000e+037.5500000000e+01
+ 3.4500000000e+037.3000000000e+01
+ 3.4550000000e+037.0500000000e+01
+ 3.4600000000e+036.8000000000e+01
+ 3.4650000000e+036.5500000000e+01
+ 3.4700000000e+036.3000000000e+01
+ 3.4750000000e+036.0500000000e+01
+ 3.4800000000e+035.8000000000e+01
+ 3.4850000000e+035.5500000000e+01
+ 3.4900000000e+035.3000000000e+01
+ 3.4950000000e+035.0500000000e+01
+ 3.5000000000e+034.8000000000e+01
+ 3.5050000000e+034.5500000000e+01
+ 3.5100000000e+034.3000000000e+01
+ 3.5150000000e+034.0500000000e+01
+ 3.5200000000e+033.8000000000e+01
+ 3.5250000000e+033.5500000000e+01
+ 3.5300000000e+033.3000000000e+01
+ 3.5350000000e+033.0500000000e+01
+ 3.5400000000e+032.8000000000e+01
+ 3.5450000000e+032.5500000000e+01
+ 3.5500000000e+032.3000000000e+01
+ 3.5550000000e+032.0500000000e+01
+ 3.5600000000e+031.8000000000e+01
+ 3.5650000000e+031.5500000000e+01
+ 3.5700000000e+031.3000000000e+01
+ 3.5750000000e+031.0500000000e+01
+ 3.5800000000e+038.0000000000e+00
+ 3.5850000000e+035.5000000000e+00
+ 3.5900000000e+033.0000000000e+00
+ 3.5950000000e+035.0000000000e-01
+
+
+
+ MAX
+ 5
+
+
+ 5.0000000000e-01
+
+
+
+ 3.5990000000e+03
+ 3.5990000000e+03
+ -inf
+ 0
+
+
+ 2.5000000000e+00
+ 5.0000000000e-01
+ -inf
+ 0
+
+
+
+ 3.0040000000e+033.0000000000e+02
+ 3.0090000000e+032.9750000000e+02
+ 3.0140000000e+032.9500000000e+02
+ 3.0190000000e+032.9250000000e+02
+ 3.0240000000e+032.9000000000e+02
+ 3.0290000000e+032.8750000000e+02
+ 3.0340000000e+032.8500000000e+02
+ 3.0390000000e+032.8250000000e+02
+ 3.0440000000e+032.8000000000e+02
+ 3.0490000000e+032.7750000000e+02
+ 3.0540000000e+032.7500000000e+02
+ 3.0590000000e+032.7250000000e+02
+ 3.0640000000e+032.7000000000e+02
+ 3.0690000000e+032.6750000000e+02
+ 3.0740000000e+032.6500000000e+02
+ 3.0790000000e+032.6250000000e+02
+ 3.0840000000e+032.6000000000e+02
+ 3.0890000000e+032.5750000000e+02
+ 3.0940000000e+032.5500000000e+02
+ 3.0990000000e+032.5250000000e+02
+ 3.1040000000e+032.5000000000e+02
+ 3.1090000000e+032.4750000000e+02
+ 3.1140000000e+032.4500000000e+02
+ 3.1190000000e+032.4250000000e+02
+ 3.1240000000e+032.4000000000e+02
+ 3.1290000000e+032.3750000000e+02
+ 3.1340000000e+032.3500000000e+02
+ 3.1390000000e+032.3250000000e+02
+ 3.1440000000e+032.3000000000e+02
+ 3.1490000000e+032.2750000000e+02
+ 3.1540000000e+032.2500000000e+02
+ 3.1590000000e+032.2250000000e+02
+ 3.1640000000e+032.2000000000e+02
+ 3.1690000000e+032.1750000000e+02
+ 3.1740000000e+032.1500000000e+02
+ 3.1790000000e+032.1250000000e+02
+ 3.1840000000e+032.1000000000e+02
+ 3.1890000000e+032.0750000000e+02
+ 3.1940000000e+032.0500000000e+02
+ 3.1990000000e+032.0250000000e+02
+ 3.2040000000e+032.0000000000e+02
+ 3.2090000000e+031.9750000000e+02
+ 3.2140000000e+031.9500000000e+02
+ 3.2190000000e+031.9250000000e+02
+ 3.2240000000e+031.9000000000e+02
+ 3.2290000000e+031.8750000000e+02
+ 3.2340000000e+031.8500000000e+02
+ 3.2390000000e+031.8250000000e+02
+ 3.2440000000e+031.8000000000e+02
+ 3.2490000000e+031.7750000000e+02
+ 3.2540000000e+031.7500000000e+02
+ 3.2590000000e+031.7250000000e+02
+ 3.2640000000e+031.7000000000e+02
+ 3.2690000000e+031.6750000000e+02
+ 3.2740000000e+031.6500000000e+02
+ 3.2790000000e+031.6250000000e+02
+ 3.2840000000e+031.6000000000e+02
+ 3.2890000000e+031.5750000000e+02
+ 3.2940000000e+031.5500000000e+02
+ 3.2990000000e+031.5250000000e+02
+ 3.3040000000e+031.5000000000e+02
+ 3.3090000000e+031.4750000000e+02
+ 3.3140000000e+031.4500000000e+02
+ 3.3190000000e+031.4250000000e+02
+ 3.3240000000e+031.4000000000e+02
+ 3.3290000000e+031.3750000000e+02
+ 3.3340000000e+031.3500000000e+02
+ 3.3390000000e+031.3250000000e+02
+ 3.3440000000e+031.3000000000e+02
+ 3.3490000000e+031.2750000000e+02
+ 3.3540000000e+031.2500000000e+02
+ 3.3590000000e+031.2250000000e+02
+ 3.3640000000e+031.2000000000e+02
+ 3.3690000000e+031.1750000000e+02
+ 3.3740000000e+031.1500000000e+02
+ 3.3790000000e+031.1250000000e+02
+ 3.3840000000e+031.1000000000e+02
+ 3.3890000000e+031.0750000000e+02
+ 3.3940000000e+031.0500000000e+02
+ 3.3990000000e+031.0250000000e+02
+ 3.4040000000e+031.0000000000e+02
+ 3.4090000000e+039.7500000000e+01
+ 3.4140000000e+039.5000000000e+01
+ 3.4190000000e+039.2500000000e+01
+ 3.4240000000e+039.0000000000e+01
+ 3.4290000000e+038.7500000000e+01
+ 3.4340000000e+038.5000000000e+01
+ 3.4390000000e+038.2500000000e+01
+ 3.4440000000e+038.0000000000e+01
+ 3.4490000000e+037.7500000000e+01
+ 3.4540000000e+037.5000000000e+01
+ 3.4590000000e+037.2500000000e+01
+ 3.4640000000e+037.0000000000e+01
+ 3.4690000000e+036.7500000000e+01
+ 3.4740000000e+036.5000000000e+01
+ 3.4790000000e+036.2500000000e+01
+ 3.4840000000e+036.0000000000e+01
+ 3.4890000000e+035.7500000000e+01
+ 3.4940000000e+035.5000000000e+01
+ 3.4990000000e+035.2500000000e+01
+ 3.5040000000e+035.0000000000e+01
+ 3.5090000000e+034.7500000000e+01
+ 3.5140000000e+034.5000000000e+01
+ 3.5190000000e+034.2500000000e+01
+ 3.5240000000e+034.0000000000e+01
+ 3.5290000000e+033.7500000000e+01
+ 3.5340000000e+033.5000000000e+01
+ 3.5390000000e+033.2500000000e+01
+ 3.5440000000e+033.0000000000e+01
+ 3.5490000000e+032.7500000000e+01
+ 3.5540000000e+032.5000000000e+01
+ 3.5590000000e+032.2500000000e+01
+ 3.5640000000e+032.0000000000e+01
+ 3.5690000000e+031.7500000000e+01
+ 3.5740000000e+031.5000000000e+01
+ 3.5790000000e+031.2500000000e+01
+ 3.5840000000e+031.0000000000e+01
+ 3.5890000000e+037.5000000000e+00
+ 3.5940000000e+035.0000000000e+00
+ 3.5990000000e+032.5000000000e+00
+
+
+
diff --git a/tests/examples/ExampleRrdGenerator.php b/tests/examples/ExampleRrdGenerator.php
new file mode 100644
index 0000000..8ee6b75
--- /dev/null
+++ b/tests/examples/ExampleRrdGenerator.php
@@ -0,0 +1,68 @@
+addDataSource('value:GAUGE:10:U:U');
+ $creator->addDataSource('extra_value:GAUGE:10:U:U'); // to test multi DS scenario
+
+ $rras = [
+ // 1 second resolution for 30 seconds
+ 'AVERAGE:0.5:1:30',
+ 'MIN:0.5:1:30',
+ 'MAX:0.5:1:30',
+ // 5 second resolution for 2 minutes (120 seconds)
+ 'AVERAGE:0.5:5:120',
+ 'MIN:0.5:5:120',
+ 'MAX:0.5:5:120',
+ ];
+
+ foreach ($rras as $rra) {
+ $creator->addArchive($rra);
+ }
+
+ $creator->save();
+ echo 'createRrd done' . PHP_EOL;
+
+ }
+
+ /**
+ * @throws \Exception
+ */
+ public static function fillRrd($filename, int $secondsCount)
+ {
+ $updater = new \RRDUpdater($filename);
+
+ echo 'fillRrd starting' . PHP_EOL;
+ $time = time();
+ for ($i = 0; $i < $secondsCount; $i++) {
+ $updater->update(
+ [
+ 'value' => '' .$i,
+ 'extra_value' => ''. (($secondsCount - $i) / 2) // just to see double values
+ ],
+ $time + $i
+ );
+ }
+ echo 'fillRrd done' . PHP_EOL;
+ }
+}
+
+$filename = 'generic-' . time() . '.rrd';
+echo "Generating: {$filename}" . PHP_EOL;
+ExampleRrdGenerator::createRrd($filename);
+ExampleRrdGenerator::fillRrd($filename, 3600);
\ No newline at end of file