Skip to content

Commit

Permalink
Better handling of default section, code optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
Programie committed Nov 17, 2015
1 parent 451d260 commit 034cf1e
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 128 deletions.
3 changes: 3 additions & 0 deletions examples/example.ini
@@ -1,3 +1,6 @@
some key = value in default section
another key = another value in default section

;This is an example section
[my section]
;And here you can see an example property
Expand Down
10 changes: 10 additions & 0 deletions examples/simple-write.php
Expand Up @@ -19,4 +19,14 @@
$property->comment = array("This is a comment for the integer value property");
$section->addProperty($property);

$section = $ini->getDefaultSection();

$section->addProperty(new Property("some key", "this property is in the default section"));

$section = new Section("another section");

$ini->addSection($section);

$section->addProperty(new Property("my array", array(1, 2, 3, 4, 5)));

$ini->save(__DIR__ . "/example-write.ini");
117 changes: 117 additions & 0 deletions src/main/php/com/selfcoders/pini/Parser.php
@@ -0,0 +1,117 @@
<?php
namespace com\selfcoders\pini;

class Parser
{
/**
* @var array
*/
private $commentBlock = array();
/**
* @var Section
*/
private $currentSection;
/**
* @var Pini
*/
private $pini;

public function __construct(Pini $pini)
{
$this->pini = $pini;
}

public function readFromFile($fileHandle)
{
while (($line = fgets($fileHandle)) !== false)
{
$this->parseLine($line);
}
}

/**
* Parse the given line.
*
* @param string $line The line to parse
*/
private function parseLine($line)
{
$line = trim($line);

// Ignore empty lines
if (!strlen($line))
{
return;
}

// This line is a comment -> write it into the current comment block
if ($line[0] == ";")
{
$this->commentBlock[] = substr($line, 1);
return;
}

// Parse a section in format "[name]"
if ($line[0] == "[" and $line[strlen($line) - 1] == "]")
{
$this->currentSection = new Section(substr($line, 1, strlen($line) - 2), $this->commentBlock);
$this->pini->addSection($this->currentSection);

$this->commentBlock = array();
return;
}

// Parse the line in format "key = value"
list($key, $value) = explode("=", $line, 2);

$key = trim($key);
$value = trim($value);

// No section defined yet -> Create a new default section without a name
if (!$this->currentSection)
{
$this->currentSection = new Section;
$this->pini->addSection($this->currentSection);
}

// The key of key-array pairs end with "[]" (e.g. value[])
if (substr($key, -2) == "[]")
{
$this->addArrayProperty(substr($key, 0, -2), $value);
}
else
{
$this->addProperty($key, $value);
}
}

private function addArrayProperty($key, $value)
{
$property = $this->currentSection->getProperty($key);
if ($property === null)
{
$property = new Property($key, array());
$this->currentSection->addProperty($property);
}

$property->value[] = $value;
$property->comment = $this->commentBlock;

$this->commentBlock = array();
}

private function addProperty($key, $value)
{
$property = $this->currentSection->getProperty($key);
if (!$property)
{
$property = new Property($key);
$this->currentSection->addProperty($property);
}

$property->value = $value;
$property->comment = $this->commentBlock;

$this->commentBlock = array();
}
}
182 changes: 54 additions & 128 deletions src/main/php/com/selfcoders/pini/Pini.php
Expand Up @@ -8,138 +8,72 @@ class Pini
*/
private $filename;
/**
* @var array An array containing all PiniSection instances
* @var array An array containing all Section instances
*/
public $sections;
/**
* @var string The name of the currently parsing section
*/
private $currentSection;
/**
* @var array The content of the currently reading comment block
*/
private $commentBlock;
public $sections = array();

public function __construct($filename = null)
{
$this->filename = $filename;

$this->init();
$this->load();
}

/**
* Initialize the content of the ini file
* Add the given section.
*
* Note: This will remove all sections from the ini file!
* @param Section $section The instance of the section
*/
private function init()
public function addSection(Section $section)
{
$this->commentBlock = array();
$this->sections = array();
$this->sections[$section->name] = $section;
}

/**
* Parse the given line.
* Get the instance of the specified section.
*
* @param string $line The line to parse
* @param string $name The name of the section to retrieve
* @return null|Section The section or null if not found
*/
private function parseLine($line)
public function getSection($name)
{
$line = trim($line);

// Ignore empty lines
if (!$line)
{
return;
}

// This line is a comment -> skip it
if ($line[0] == ";")
{
$this->commentBlock[] = substr($line, 1);
return;
}

// Parse a section in format "[name]"
if ($line[0] == "[" and $line[strlen($line) - 1] == "]")
{
$this->currentSection = new Section(substr($line, 1, strlen($line) - 2), $this->commentBlock);
$this->addSection($this->currentSection);

$this->commentBlock = array();
return;
}

// Parse the line in format "key = value"
list($key, $value) = explode("=", $line, 2);

$key = trim($key);
$value = trim($value);

// No section defined yet -> Create a new default section without a name
if (!$this->currentSection)
{
$this->currentSection = new Section();
$this->addSection($this->currentSection);
}

// The key of key-array pairs end with "[]" (e.g. value[])
if (substr($key, -2) == "[]")
{
// This is a key-array pair (a key with multiple values)
$key = substr($key, 0, -2);

$property = $this->currentSection->getProperty($key);
if (!$property)
{
$property = new Property($key, array());
$this->currentSection->addProperty($property);
}

$property->value[] = $value;
}
else
if (!isset($this->sections[$name]))
{
// This is a normal key-value pair
$property = $this->currentSection->getProperty($key);
if (!$property)
{
$property = new Property($key);
$this->currentSection->addProperty($property);
}

$property->value = $value;
return null;
}

$property->comment = $this->commentBlock;
$this->commentBlock = array();
return $this->sections[$name];
}

/**
* Add the given section.
* Get the instance of the default section.
*
* @param Section $section The instance of the section
* The default section contains all properties outside of any section.
*
* A new section will be created if there is no default section yet.
*
* @return Section The instance of the default section
*/
public function addSection(Section $section)
public function getDefaultSection()
{
$this->sections[$section->name] = $section;
$section = $this->getSection("");
if ($section === null)
{
$section = new Section;
$this->addSection($section);
}

return $section;
}

/**
* Get the instance of the specified section.
* Remove all sections.
*
* @param string $name The name of the section to retrieve
* @return null|Section The section or null if not found
* Note: This will not destroy the section instances.
*/
public function getSection($name)
public function removeAllSections()
{
if (!isset($this->sections[$name]))
{
return null;
}

return $this->sections[$name];
$this->sections = array();
}

/**
Expand Down Expand Up @@ -193,20 +127,19 @@ public function load($filename = null)
return false;
}

$file = fopen($filename, "r");
if (!$file)
$fileHandle = fopen($filename, "r");
if ($fileHandle === false)
{
return false;
}

$this->init();
$this->removeAllSections();

while (($line = fgets($file)) !== false)
{
$this->parseLine($line);
}
$parser = new Parser($this);

fclose($file);
$parser->readFromFile($fileHandle);

fclose($fileHandle);

return true;
}
Expand Down Expand Up @@ -235,40 +168,33 @@ public function save($filename = null)
return false;
}

$defaultSection = $this->getDefaultSection();

foreach ($defaultSection->comment as $commentLine)
{
fputs($file, ";" . $commentLine . "\n");
}

$defaultSection->writePropertiesToFile($file);

/**
* @var $section Section
*/
foreach ($this->sections as $section)
{
if ($section->name == "")
{
continue;
}

foreach ($section->comment as $commentLine)
{
fputs($file, ";" . $commentLine . "\n");
}

fputs($file, "[" . $section->name . "]\n");

/**
* @var $property Property
*/
foreach ($section->properties as $property)
{
foreach ($property->comment as $commentLine)
{
fputs($file, ";" . $commentLine . "\n");
}

if (is_array($property->value))
{
foreach ($property->value as $arrayValue)
{
fputs($file, $property->name . "[] = " . $arrayValue . "\n");
}
}
else
{
fputs($file, $property->name . " = " . $property->value . "\n");
}
}
$section->writePropertiesToFile($file);
}

fclose($file);
Expand Down

0 comments on commit 034cf1e

Please sign in to comment.