Skip to content

Commit

Permalink
INIT
Browse files Browse the repository at this point in the history
  • Loading branch information
vvval committed Feb 15, 2016
1 parent 050b743 commit f65c685
Show file tree
Hide file tree
Showing 11 changed files with 335 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitIgnore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# binary
Lightweight tool to read/write tons of data directly in file, skipping memory usage
Lightweight tool to read/write tons of data directly in file, skipping memory usage
23 changes: 23 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "vvval/binary",
"description": "Lightweight tool to read/write tons of data directly in file, skipping memory usage",
"authors": [
{
"name": "Valentin V / vvval",
"email": "[email protected]"
}
],
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"autoload": {
"psr-4": {
"Vvval\\Binary\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Vvval\\Binary\\Tests\\": "tests"
}
}
}
18 changes: 18 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
stopOnError="false"
syntaxCheck="true">
<testsuites>
<testsuite name="Application Tests">
<directory>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
200 changes: 200 additions & 0 deletions src/BinaryGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<?php
/**
* Lightweight tool to read/write tons of data directly in file, skipping memory usage
*
* @author Valentin V
* @license http://www.opensource.org/licenses/MIT
* @link https://github.com/vvval/binary
* @version 0.1.0
*/
namespace Vvval\Binary;

use Vvval\Binary\Exceptions\HandlerException;
use Vvval\Binary\Exceptions\ReadDataException;
use Vvval\Binary\Exceptions\WriteDataException;

class BinaryGenerator
{
/**
* todo read about fopen
*/
const READ = 'rb';
const WRITE = 'wb';
const APPEND = 'ab';

private $filename = null;
private $compression = null;
private $handler = null;
private $mode = self::READ;

/**
* @param $compression
* @return $this
* @throws HandlerException
*/
public function setCompression($compression)
{
if (!empty($this->handler))
{
throw new HandlerException("Binary generator has already started with \"$this->filename\" file.");
}

$this->compression = $compression;

return $this;
}

/**
* @param $filename
* @param $mode
* @throws HandlerException
*/
public function start($filename, $mode)
{
$this->mode = $mode;
$this->filename = $filename;

if (!empty($this->handler))
{
throw new HandlerException("Binary generator has already started with \"$this->filename\" file.");
}

if (!empty($this->compression))
{
$this->handler = gzopen($this->filename, $this->mode);
}
else
{
$this->handler = fopen($this->filename, $this->mode);
}

if (empty($this->handler))
{
throw new HandlerException("Error during opening \"$this->filename\" file.");
}
}

/**
*
*/
public function finish()
{
if (!empty($this->handler))
{
if (!empty($this->compression))
{
gzclose($this->handler);
}
else
{
fclose($this->handler);
}

$this->handler = null;
}
}

/**
* @param $data
* @return int
* @throws HandlerException
* @throws WriteDataException
*/
public function writeData($data)
{
if (!$this->isWriteMode())
{
throw new WriteDataException("Unable to write data into \"$this->filename\" file, read mode is set.");
}

if (empty($this->handler))
{
throw new HandlerException("Unable to write data into \"$this->filename\" file, no resource is available.");
}

$packedLength = pack('L', mb_strlen($data));

if (!empty($this->compression))
{
return gzwrite($this->handler, $packedLength . $data);
}

return fwrite($this->handler, $packedLength . $data);
}

/**
* @return null|string
* @throws HandlerException
* @throws ReadDataException
*/
public function readData()
{
if (!$this->isReadMode())
{
throw new ReadDataException("Unable to read data from \"$this->filename\" file, write mode is set.");
}

if (empty($this->handler))
{
throw new HandlerException("Unable to read data from \"$this->filename\" file, no resource is available.");
}

if (!empty($this->compression))
{
$length = gzread($this->handler, 4);
}
else
{
$length = fread($this->handler, 4);
}

if (empty($length))
{
return null;
}

if (mb_strlen($length) != 4)
{
throw new ReadDataException("Unable to read data from \"$this->filename\" file, data is corrupted.");
}

$length = unpack('L', $length);

if (!empty($this->compression))
{
return gzread($this->handler, $length[1]);
}
else
{
return fread($this->handler, $length[1]);
}
}

/**
* @return bool
*/
private function isReadMode()
{
return $this->mode === self::READ;
}

/**
* @return bool
*/
private function isWriteMode()
{
return in_array($this->mode, [self::WRITE, self::APPEND]);
}

/**
* Check if file was closed.
*
*/
public function __destruct()
{
if (!empty($this->handler))
{
throw new HandlerException("Binary generator hasn't finished \"$this->filename\" file yet.");
}
}
}
15 changes: 15 additions & 0 deletions src/Exceptions/GeneratorException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Lightweight tool to read/write tons of data directly in file, skipping memory usage
*
* @author Valentin V
* @license http://www.opensource.org/licenses/MIT
* @link https://github.com/vvval/binary
* @version 0.1.0
*/
namespace Vvval\Binary\Exceptions;

class GeneratorException extends \Exception
{

}
15 changes: 15 additions & 0 deletions src/Exceptions/HandlerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Lightweight tool to read/write tons of data directly in file, skipping memory usage
*
* @author Valentin V
* @license http://www.opensource.org/licenses/MIT
* @link https://github.com/vvval/binary
* @version 0.1.0
*/
namespace Vvval\Binary\Exceptions;

class HandlerException extends GeneratorException
{

}
15 changes: 15 additions & 0 deletions src/Exceptions/ReadDataException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Lightweight tool to read/write tons of data directly in file, skipping memory usage
*
* @author Valentin V
* @license http://www.opensource.org/licenses/MIT
* @link https://github.com/vvval/binary
* @version 0.1.0
*/
namespace Vvval\Binary\Exceptions;

class ReadDataException extends GeneratorException
{

}
15 changes: 15 additions & 0 deletions src/Exceptions/WriteDataException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Lightweight tool to read/write tons of data directly in file, skipping memory usage
*
* @author Valentin V
* @license http://www.opensource.org/licenses/MIT
* @link https://github.com/vvval/binary
* @version 0.1.0
*/
namespace Vvval\Binary\Exceptions;

class WriteDataException extends GeneratorException
{

}
32 changes: 32 additions & 0 deletions tests/BinaryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Created by PhpStorm.
* User: Valentin
* Date: 01.02.2016
* Time: 13:19
*/

namespace Vvval\Binary\Tests;

use Vvval\Binary\BinaryGenerator;

class BinaryTest extends \PHPUnit_Framework_TestCase
{
private $writeFile = 'binary.write.txt';
private $appendFile = 'binary.append.txt';

/**
* If data file exists.
*/
public function testBinaryWrite()
{
$binary = new BinaryGenerator();

$binary->start($this->writeFile, BinaryGenerator::WRITE);
$binary->writeData('some data.1');
$binary->writeData('some data.2');
$binary->finish();

$this->assertFileExists($this->writeFile);
}
}
Empty file added tests/assets/.empty
Empty file.

0 comments on commit f65c685

Please sign in to comment.