From d59a4921188753dbe4c0161081755a28112c3ef6 Mon Sep 17 00:00:00 2001 From: Nathan Gass Date: Thu, 22 Mar 2012 18:18:42 +0000 Subject: Branch itools/devel-utf8 created --- devel-utf8/it_pipe.class | 209 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 devel-utf8/it_pipe.class (limited to 'devel-utf8/it_pipe.class') diff --git a/devel-utf8/it_pipe.class b/devel-utf8/it_pipe.class new file mode 100644 index 0000000..d002b5b --- /dev/null +++ b/devel-utf8/it_pipe.class @@ -0,0 +1,209 @@ + 1, 'preg_match' => 1, 'preg_split' => 1, 'it__match' => 1); + +/** + * Creates a pipe object from input. Named arguments: + * $p['fn'] filename to read lines from + * $p['cmd'] cmd to read lines from + * $p['data'] data to read line from. either array of lines without newslines or string + */ +function __construct($p = array()) +{ + if ($p['data']) + $this->lines = $p['data']; + else if ($p['cmd']) + $this->lines = strlen($data = it::exec($p['cmd'], $p['args'])) ? explode("\n", rtrim($data, "\n")) : array(); + else + foreach ((array)($p['fn'] ? $p['fn'] : "php://stdin") as $fn) + $this->lines = array_merge((array)$this->lines, file($fn, FILE_IGNORE_NEW_LINES)); +} + +/** + * Apply any php function to every line in pipe. Pass line as first arg except with some functions (e.g. explode) + */ +function __call($name, $params) +{ + list($parampos) = self::$lastargfunc[$name] ? array(count($params)) : array(0, array_unshift($params, "")); + $func = ($t = it::match('(\w+)__(\w+)', $name)) ? array($t[0], $t[1]) : (method_exists($this, $name) ? array($this, $name) : $name); + + foreach($this->lines as $i => $params[$parampos]) + $this->lines[$i] = call_user_func_array($func, $params); + + return $this; +} + +function __toString() +{ + return is_array($this->lines) ? join("\n", $this->lines) . "\n" : ""; +} + + +# +# Internal: Implement iterator +# +function rewind() +{ + reset($this->lines); + $this->next(); +} + +function next() +{ + $this->valid = each($this->lines); +} + +function valid() +{ + return $this->valid; +} + +function current() +{ + return $this->valid[1]; +} + +function key() +{ + return $this->valid[0]; +} + + +/** + * Apply an expression to every line + */ +function map($expr) +{ + $this->lines = it::map($expr, $this->lines); + + return $this; +} + +/** + * Convert pipe from utf8 to iso-latin + */ +function latin() +{ + return $this->map('utf8_decode($v)'); +} + +/** + * Convert pipe from iso-latin to uft8 + */ +function utf8() +{ + return $this->map('utf8_encode($v)'); +} + +/** + * Return contents of pipe as key->val pair (key must be tab separated) + */ +function keyval() +{ + foreach ($this->lines as $line) + { + list($key, $val) = explode("\t", $line, 2); + $result[$key] = $val; + } + + return (array)$result; +} + +/** + * Swap first two columns + */ +function swap() +{ + foreach ($this->lines as $idx => $line) + { + list($col1, $col2) = explode("\t", $line, 2); + $this->lines[$idx] = "$col2\t$col1"; + } + + return $this; +} + +function ED() +{ + ED($this->lines); + + return $this; +} + +/** + * Convert every line into an object with named columns + * @param collist comma separator column name list + * @param separator split character ["\t"] + */ +function cols($collist, $separator = "\t") +{ + $keys = explode(",", $collist); + foreach ($this->lines as $idx => $line) + $this->lines[$idx] = (object)array_combine($keys, explode($separator, $line)); + + return $this; +} + +/** + * Return contents of pipe as associative records + */ +function csv() +{ + $counts = count_chars($this->lines[0]); + $splitchar = $counts[ord("\t")] ? "\t" : ($counts[ord(";")] > $counts[ord(",")] ? ";" : ","); + $schema = str_getcsv(trim(array_shift($this->lines), "#\n "), $splitchar, '"'); # could do a function_exists('str_getcsv') here... + foreach (preg_grep('/^$/', $schema) as $idx => $dummy) + $schema[$idx] = "field$idx"; + + $oldlocale = setlocale(LC_CTYPE, 'de_CH.iso-8859-1'); + + foreach ($this->lines as $line) + $records[] = (object)array_combine($schema, str_getcsv($line, $splitchar, '"')); # could do a function_exists('str_getcsv') here... + + setlocale(LC_CTYPE, $oldlocale); + + return (array)$records; +} + +/** + * Return contents of pipe as array of lines + */ +function lines() +{ + return $this->lines; +} + +/** + * Pipe our contents through a shell command + */ +function pipe($cmd) +{ + $descriptors = array(0 => array("pipe", "r"), 1 => array("pipe", "w")); + $process = proc_open($cmd, $descriptors, $pipes); + + fwrite($pipes[0], join("\n", $this->lines) . ($this->lines ? "\n" :"")); + fclose($pipes[0]); + + $this->lines = explode("\n", rtrim(stream_get_contents($pipes[1]))); + $this->key = 0; + fclose($pipes[1]); + proc_close($process); + + return $this; +} + +/** + * Save our contents in a file + * @param $fn filename to save in + * @param $append append to file (boolean) + */ +function save($fn, $append = false) +{ + file_put_contents($fn, $this->lines ? join("\n", $this->lines) . "\n" : "", $append ? FILE_APPEND : 0); + + return $this; +} + +} -- cgit v1.2.3