g2 Mon Jun 22 00:19:12 2009 UTC Added files: /phpruntests/code-samples/taskScheduler/classes taskSchedulerFile.php taskSchedulerMsgQ.php /phpruntests/code-samples/taskScheduler results.xls
Modified files: /phpruntests/code-samples/taskScheduler/classes taskScheduler.php /phpruntests/code-samples/taskScheduler run.php Log: phpruntests - update taskScheduler (prototype) - added file-driven ipc
http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/classes/taskScheduler.php?r1=1.2&r2=1.3&diff_format=u Index: phpruntests/code-samples/taskScheduler/classes/taskScheduler.php diff -u phpruntests/code-samples/taskScheduler/classes/taskScheduler.php:1.2 phpruntests/code-samples/taskScheduler/classes/taskScheduler.php:1.3 --- phpruntests/code-samples/taskScheduler/classes/taskScheduler.php:1.2 Tue Jun 16 22:43:30 2009 +++ phpruntests/code-samples/taskScheduler/classes/taskScheduler.php Mon Jun 22 00:19:12 2009 @@ -1,24 +1,17 @@ <?php -declare(ticks=true); - - class taskScheduler { - const MSG_QUEUE_KEY = 1234; // id of the message-queue - const MSG_QUEUE_SIZE = 1024; // max-size of a single message - const KILL_CHILD = 'killBill'; // kill-signal to terminate a child - - private $taskList = array(); // the list of the tasks to be executed - private $processCount = NULL; // the number of processes - private $inputQueue = NULL; // the input-queue (only used by the sender) - private $pidStore = array(); // stores the pids of all child-processes - private $time = 0; // the needed time - private $countPass = 0; // counts the passed tasks - private $countFail = 0; // counts the failed tasks - private $groupTasks = false; // are the tasks stored in groups? - private $memStore = array(); // stores the mem-usage after an incomming task + protected $taskList = array(); // the list of the tasks to be executed + protected $processCount = 0; // the number of processes + + protected $time = 0; // the needed time + protected $countPass = 0; // counts the passed tasks + protected $countFail = 0; // counts the failed tasks + protected $memStore = array(); // stores the mem-usage after an incomming task + + /** * the constructor @@ -34,24 +27,31 @@ $this->setProcessCount($processCount); } + + + public static function getInstance(array $taskList=NULL, $processCount=NUL, $useMsgQ=false) + { + if (extension_loaded('pcntl')) { + + if ($useMsgQ === true) { + + return new taskSchedulerMsgQ($taskList, $processCount); + } + + return new taskSchedulerFile($taskList, $processCount); + } + + return new taskScheduler($taskList, $processCount); + } /** * sets the task-list which has to be an array of task-objects. - * it's also possible to use a multidimensional array. in this case the - * tasks are distributed to the child-processes exactly in the way as they - * are grouped in the list. the first-level index strictly has to be - * numeric and continuous starting with zero. - * + * * @param array $taskList */ public function setTaskList(array $taskList) { - if (is_array($taskList[0])) { - $this->groupTasks = true; - $this->processCount = sizeof($taskList); - } - $this->taskList = $taskList; } @@ -74,64 +74,18 @@ */ public function setProcessCount($processCount) { - if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { + if (is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** - * removes the used message-queues. - */ - private static function cleanUp() - { - @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY)); - @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1)); - logg("CLEAN UP"); - } - - - /** - * the signal-handler is called by the interrupt- or quit-signal and calls - * the cleanUp-method. - * - * @param int $signal - */ - public static function signalHandler($signal) - { - logg("SIGNAL: $signal"); - - switch($signal) { - - case SIGINT: - case SIGQUIT: - self::cleanUp(); - die("\n"); - break; - - default: - break; - } - } - - /** - * switch to run the classic- or the fork-mode - */ - public function run() - { - if ($this->processCount > 0) { - $this->runFork(); - } - else $this->runClassic(); - } - - - /** * executes the tasks in a simple loop * * @return void */ - private function runClassic() + public function run() { $s = microtime(true); @@ -147,6 +101,8 @@ $this->countFail++; } + $this->memStore[] = memory_get_usage(true); + print "."; flush(); @@ -162,256 +118,6 @@ /** - * starts the sender, the receiver and forks the defined - * number of child-processes. - * - * @return void - */ - private function runFork() - { - $startTime = microtime(true); - - // register signal-handler - pcntl_signal(SIGINT, "taskScheduler::signalHandler"); - pcntl_signal(SIGQUIT, "taskScheduler::signalHandler"); - - // trim the processCount if nesecarry - if (is_null($this->processCount) || $this->processCount > sizeof($this->taskList)) { - $this->processCount = sizeof($this->taskList); - } - - // fork the child-processes - for ($i=0; $i<=$this->processCount; $i++) { - - $this->pidStore[$i] = pcntl_fork(); - - switch ($this->pidStore[$i]) { - - case -1: // failure - die("could not fork"); - break; - - case 0: // child - if ($i==0) { - $this->sender(); - } else { - $cid = ($this->groupTasks == true) ? $i : NULL; - $this->child($cid); - } - break; - - default: // parent - break; - } - } - - // start the receiver - $this->receiver(); - - // wait until all child-processes are terminated - for ($i=0; $i<=$this->processCount; $i++) { - - pcntl_waitpid($this->pidStore[$i], $status); - logg("child $i terminated - status $status"); - } - - $endTime = microtime(true); - $this->time = round($endTime-$startTime,5); - - // remove the msg-queue - self::cleanUp(); - - logg("EXIT MAIN"); - return; - } - - - /** - * the receiver is listening to the result-queue and stores the incomming - * tasks back to the task-list. - * when finished it sends the kill-signal to all children and terminates - * itself. - * - * @return void - */ - private function receiver() - { - logg("RECEIVER START - ".sizeof($this->taskList)." tasks"); - - $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); - - $task = ''; - $type = 1; - - if ($this->groupTasks == true) { - $limit = 0; - foreach ($this->taskList as $list) { - $limit += sizeof($list); - } - } else { - $limit = sizeof($this->taskList); - } - - for ($i=0; $i<$limit; $i++) { - - $this->memStore[] = memory_get_usage(true); - - if (msg_receive($resultQueue, 0, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { - - // check state - if ($task->getState() == task::PASS) { - $this->countPass++; - } else { - $this->countFail++; - } - - // store result - $index = $task->getIndex(); - - if ($this->groupTasks == true) { - $this->taskList[$type-2][$index] = $task; - logg("RECEIVER store task ".($type-1)."-$index"); - - } else { - $this->taskList[$index] = $task; - logg("RECEIVER store task $index"); - } - - - } - else logg("RECEIVER ERROR $error"); - } - - $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - - for ($i=1; $i<=$this->processCount; $i++) { - - if (msg_send($inputQueue, $i, self::KILL_CHILD, true, true, $error)) { - - logg("RECEIVER send KILL_CHILD"); - } - else logg("RECEIVER ERROR $error"); - } - - logg("RECEIVER EXIT"); - return; - } - - - /** - * the sender is passes through the task-list and distributes the single - * tasks to the child-processes using the input-queue. - * when finished it terminates itself. - * - * @return void - */ - private function sender() - { - logg("SENDER START - ".sizeof($this->taskList)." tasks"); - - $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - - for ($i=0; $i<sizeof($this->taskList); $i++) { - - if ($this->groupTasks == true) { - - for ($j=0; $j<sizeof($this->taskList[$i]); $j++) { - - $this->sendTask($this->taskList[$i][$j], $j, $i+1); - } - - } else { - - $this->sendTask($this->taskList[$i], $i); - } - } - - logg("SENDER EXIT"); - exit(0); - } - - - /** - * helper-class of sender. - * sends a task to a child-process using the input-queue. - * - * @param task $task the task to send - * @param int $index the task's index in the taskList - * @param int $type the message-type (default=1) - * @return void - */ - private function sendTask(task $task, $index, $type=1) - { - $task->setIndex($index); - - if (msg_send($this->inputQueue, $type, $task, true, true, $error)) { - - logg("SENDER send task $type - $index"); - } - else logg("SENDER ERROR $error"); - - return; - } - - - /** - * the child is listening to the input-queue and executes the incomming - * tasks. afterwards it setts the task-state and sends it back to the - * receiver via the result-queue. - * after receiving the kill-signal from the receiver it terminates itself. - * - * @param int $cid the child-id (default=NULL) - * @return void - */ - private function child($cid=NULL) - { - if (is_null($cid)) { - $cid = 0; - } - - logg("child $cid START"); - - $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); - $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); - - $type = 1; - - while (true) { - - if (msg_receive($inputQueue, $cid, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { - - if ($task == self::KILL_CHILD) - break; - - $index = $task->getIndex(); - - logg("child $cid - run task $index"); - - if ($task->run() === true) { - $task->setState(task::PASS); - } else { - $task->setState(task::FAIL); - } - - print "."; - flush(); - - if (msg_send($resultQueue, $cid+1, $task, true, true, $error)) { - - logg("child $cid - send task $index"); - } - else logg("child $cid ERROR $error"); - - } - else logg("child $cid ERROR $error"); - } - - logg("child $cid EXIT"); - exit(0); - } - - - /** * prints the statistic * * @return void @@ -420,7 +126,7 @@ { print "\n----------------------------------------\n"; - if ($this->groupTasks == true) { + if (is_array($this->taskList[0])) { $count = 0; foreach ($this->taskList as $list) { http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/run.php?r1=1.2&r2=1.3&diff_format=u Index: phpruntests/code-samples/taskScheduler/run.php diff -u phpruntests/code-samples/taskScheduler/run.php:1.2 phpruntests/code-samples/taskScheduler/run.php:1.3 --- phpruntests/code-samples/taskScheduler/run.php:1.2 Tue Jun 16 22:43:30 2009 +++ phpruntests/code-samples/taskScheduler/run.php Mon Jun 22 00:19:12 2009 @@ -1,6 +1,8 @@ <?php include 'classes/taskScheduler.php'; +include 'classes/taskSchedulerMsgQ.php'; +include 'classes/taskSchedulerFile.php'; include 'classes/taskInterface.php'; include 'classes/task.php'; @@ -25,14 +27,15 @@ $argc = sizeof($argv); -if ($argc >= 2 || $argc <= 3) { +if ($argc >= 2 || $argc <= 4) { $src = $argv[1]; $count = isset($argv[2]) ? $argv[2] : NULL; + $useMsgQ = isset($argv[3]); } else { - die("USAGE: php run.php example processCount\n"); + die("USAGE: php run.php example processCount useMsgQ\n"); } @@ -50,20 +53,21 @@ $taskList = createTaskList($count); + // init scheduler -$c = new taskScheduler(); +$c = taskScheduler::getInstance($taskList, $count, $useMsgQ); + $c->setTaskList($taskList); $c->setProcessCount($count); $c->run(); -$c->printStatistic(); - -// var_dump($c->getTaskList()); +$c->printStatistic(); $c->printFailedTasks(); - $c->printMemStatistic(10); +// var_dump($c->getTaskList()); + exit(0); ?> http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/classes/taskSchedulerFile.php?view=markup&rev=1.1 Index: phpruntests/code-samples/taskScheduler/classes/taskSchedulerFile.php +++ phpruntests/code-samples/taskScheduler/classes/taskSchedulerFile.php <?php class taskSchedulerFile extends taskScheduler { const TMP_FILE = 'taskFile'; private $inputQueue = NULL; // the input-queue (only used by the sender) private $pidStore = array(); // stores the pids of all child-processes private $groupTasks = false; // are the tasks stored in groups? private $tmpTaskList = array(); /** * the constructor * * @param array $taskList (optional) * @param int $processCount (optional) */ public function __construct(array $taskList=NULL, $processCount=NULL) { if (is_array($taskList)) { $this->setTaskList($taskList); } $this->setProcessCount($processCount); } /** * sets the task-list which has to be an array of task-objects. * it's also possible to use a multidimensional array. in this case the * tasks are distributed to the child-processes exactly in the way as they * are grouped in the list. the first-level index strictly has to be * numeric and continuous starting with zero. * * @param array $taskList * @Overrides */ public function setTaskList(array $taskList) { if (is_array($taskList[0])) { $this->groupTasks = true; $this->processCount = sizeof($taskList); } $this->taskList = $taskList; } /** * sets the number of child-processes. * in the case of using a multidimensional task-list this parameter is * ignored and set to the number of task-groups. * * @param int $count * @Overrides */ public function setProcessCount($processCount) { if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** * starts the sender, the receiver and forks the defined * number of child-processes. * * @return void * @Overrides */ public function run() { if ($this->processCount == 0) { return parent::run(); } $startTime = microtime(true); // trim the processCount if nesecarry if ($this->processCount > sizeof($this->taskList)) { $this->processCount = sizeof($this->taskList); } $this->createTaskFiles(); // fork the child-processes for ($i=1; $i<=$this->processCount; $i++) { $this->pidStore[$i] = pcntl_fork(); switch ($this->pidStore[$i]) { case -1: // failure die("could not fork"); break; case 0: // child $this->child($i-1); break; default: // parent break; } } // wait until all child-processes are terminated for ($i=0; $i<$this->processCount; $i++) { pcntl_waitpid($this->pidStore[$i], $status); logg("child $i terminated - status $status"); } // ensure that the tmp-files are completly written sleep(1); // collecting the results $this->receiver($i); $endTime = microtime(true); $this->time = round($endTime-$startTime,5); logg("EXIT MAIN"); return; } /** * creates a temporary file for each child which stores the allocated * array-indices. * */ private function createTaskFiles() { $taskStr = array(); if ($this->groupTasks == true) { $c = 0; foreach ($this->taskList as $key => $list) { for ($i=0; $i<sizeof($list); $i++) { $taskStr[$key] .= $i.';'; } } } else { for ($i=0; $i<sizeof($this->taskList); $i++) { $taskStr[$i%$this->processCount] .= $i.';'; } } for ($i=0; $i<$this->processCount; $i++) { file_put_contents(self::TMP_FILE.$i, $taskStr[$i]); } } /** * @return void */ private function receiver() { logg("RECEIVER START"); for ($cid=0; $cid<$this->processCount; $cid++) { $response = file_get_contents(self::TMP_FILE.$cid); $response = explode("\n", $response); array_pop($response); foreach ($response as $task) { $task = unserialize($task); if ($task->getState() == task::PASS) { $this->countPass++; } else { $this->countFail++; } $index = $task->getIndex(); if ($this->groupTasks == true) { $this->taskList[$cid][$index] = $task; } else { $this->taskList[$index] = $task; } } unlink(self::TMP_FILE.$cid); } return; } /** * @param int $cid the child-id * @return void */ private function child($cid) { logg("child $cid START"); $indexList = file_get_contents(self::TMP_FILE.$cid); $indexList = explode(';', $indexList); array_pop($indexList); $response = ''; foreach ($indexList as $index) { logg("child $cid - run task $index"); if ($this->groupTasks == true) { $task = $this->taskList[$cid][$index]; } else { $task = $this->taskList[$index]; } if ($task->run() === true) { $task->setState(task::PASS); } else { $task->setState(task::FAIL); } $task->setIndex($index); print "."; flush(); $response .= serialize($task)."\n"; } file_put_contents(self::TMP_FILE.$cid, $response, LOCK_EX); logg("child $cid EXIT"); exit(0); } /** * prints the statistic * * @return void */ public function printStatistic() { print "\n----------------------------------------\n"; if (is_array($this->taskList[0])) { $count = 0; foreach ($this->taskList as $list) { $count += sizeof($list); } print "Groups:\t\t".sizeof($this->taskList)."\n"; print "Tasks:\t\t".$count."\n"; } else { $count = sizeof($this->taskList); print "Tasks:\t\t".$count."\n"; } print "PASSED:\t\t".$this->countPass." (".round($this->countPass/$count*100,2)."%)\n"; print "FAILED:\t\t".$this->countFail." (".round($this->countFail/$count*100,2)."%)\n"; print "Processes:\t".$this->processCount."\n"; print "Seconds:\t".$this->time."\n"; print "----------------------------------------\n"; flush(); } public function printMemStatistic($int=10) {} } ?> http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php?view=markup&rev=1.1 Index: phpruntests/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php +++ phpruntests/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php <?php declare(ticks=true); class taskSchedulerMsgQ extends taskScheduler { const MSG_QUEUE_KEY = 1234; // id of the message-queue const MSG_QUEUE_SIZE = 1024; // max-size of a single message const KILL_CHILD = 'killBill'; // kill-signal to terminate a child private $inputQueue = NULL; // the input-queue (only used by the sender) private $pidStore = array(); // stores the pids of all child-processes private $groupTasks = false; // are the tasks stored in groups? /** * sets the task-list which has to be an array of task-objects. * it's also possible to use a multidimensional array. in this case the * tasks are distributed to the child-processes exactly in the way as they * are grouped in the list. the first-level index strictly has to be * numeric and continuous starting with zero. * * @param array $taskList * @Overrides */ public function setTaskList(array $taskList) { if (is_array($taskList[0])) { $this->groupTasks = true; $this->processCount = sizeof($taskList); } $this->taskList = $taskList; } /** * sets the number of child-processes. * in the case of using a multidimensional task-list this parameter is * ignored and set to the number of task-groups. * * @param int $count * @Overrides */ public function setProcessCount($processCount) { if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** * removes the used message-queues. */ private static function cleanUp() { @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY)); @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1)); logg("CLEAN UP"); } /** * the signal-handler is called by the interrupt- or quit-signal and calls * the cleanUp-method. * * @param int $signal */ public static function signalHandler($signal) { logg("SIGNAL: $signal"); switch($signal) { case SIGINT: case SIGQUIT: self::cleanUp(); die("\n"); break; default: break; } } /** * starts the sender, the receiver and forks the defined * number of child-processes. * * @return void * @Overrides */ public function run() { if ($this->processCount == 0) { return parent::run(); } $startTime = microtime(true); // register signal-handler pcntl_signal(SIGINT, "taskSchedulerMsgQ::signalHandler"); pcntl_signal(SIGQUIT, "taskSchedulerMsgQ::signalHandler"); // trim the processCount if nesecarry if ($this->processCount > sizeof($this->taskList)) { $this->processCount = sizeof($this->taskList); } // fork the child-processes for ($i=0; $i<=$this->processCount; $i++) { $this->pidStore[$i] = pcntl_fork(); switch ($this->pidStore[$i]) { case -1: // failure die("could not fork"); break; case 0: // child if ($i==0) { $this->sender(); } else { $cid = ($this->groupTasks == true) ? $i : NULL; $this->child($cid); } break; default: // parent break; } } // start the receiver $this->receiver(); // wait until all child-processes are terminated for ($i=0; $i<=$this->processCount; $i++) { pcntl_waitpid($this->pidStore[$i], $status); logg("child $i terminated - status $status"); } $endTime = microtime(true); $this->time = round($endTime-$startTime,5); // remove the msg-queue self::cleanUp(); logg("EXIT MAIN"); return; } /** * the receiver is listening to the result-queue and stores the incomming * tasks back to the task-list. * when finished it sends the kill-signal to all children and terminates * itself. * * @return void */ private function receiver() { logg("RECEIVER START - ".sizeof($this->taskList)." tasks"); $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); $task = ''; $type = 1; if ($this->groupTasks == true) { $limit = 0; foreach ($this->taskList as $list) { $limit += sizeof($list); } } else { $limit = sizeof($this->taskList); } for ($i=0; $i<$limit; $i++) { $this->memStore[] = memory_get_usage(true); if (msg_receive($resultQueue, 0, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { // check state if ($task->getState() == task::PASS) { $this->countPass++; } else { $this->countFail++; } // store result $index = $task->getIndex(); if ($this->groupTasks == true) { $this->taskList[$type-2][$index] = $task; logg("RECEIVER store task ".($type-1)."-$index"); } else { $this->taskList[$index] = $task; logg("RECEIVER store task $index"); } } else logg("RECEIVER ERROR $error"); } $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); for ($i=1; $i<=$this->processCount; $i++) { if (msg_send($inputQueue, $i, self::KILL_CHILD, true, true, $error)) { logg("RECEIVER send KILL_CHILD"); } else logg("RECEIVER ERROR $error"); } logg("RECEIVER EXIT"); return; } /** * the sender is passes through the task-list and distributes the single * tasks to the child-processes using the input-queue. * when finished it terminates itself. * * @return void */ private function sender() { logg("SENDER START - ".sizeof($this->taskList)." tasks"); $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); for ($i=0; $i<sizeof($this->taskList); $i++) { if ($this->groupTasks == true) { for ($j=0; $j<sizeof($this->taskList[$i]); $j++) { $this->sendTask($this->taskList[$i][$j], $j, $i+1); } } else { $this->sendTask($this->taskList[$i], $i); } } logg("SENDER EXIT"); exit(0); } /** * helper-class of sender. * sends a task to a child-process using the input-queue. * * @param task $task the task to send * @param int $index the task's index in the taskList * @param int $type the message-type (default=1) * @return void */ private function sendTask(task $task, $index, $type=1) { $task->setIndex($index); if (msg_send($this->inputQueue, $type, $task, true, true, $error)) { logg("SENDER send task $type - $index"); } else logg("SENDER ERROR $error"); return; } /** * the child is listening to the input-queue and executes the incomming * tasks. afterwards it setts the task-state and sends it back to the * receiver via the result-queue. * after receiving the kill-signal from the receiver it terminates itself. * * @param int $cid the child-id (default=NULL) * @return void */ private function child($cid=NULL) { if (is_null($cid)) { $cid = 0; } logg("child $cid START"); $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); $type = 1; while (true) { if (msg_receive($inputQueue, $cid, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { if ($task == self::KILL_CHILD) break; $index = $task->getIndex(); logg("child $cid - run task $index"); if ($task->run() === true) { $task->setState(task::PASS); } else { $task->setState(task::FAIL); } print "."; flush(); if (msg_send($resultQueue, $cid+1, $task, true, true, $error)) { logg("child $cid - send task $index"); } else logg("child $cid ERROR $error"); } else logg("child $cid ERROR $error"); } logg("child $cid EXIT"); exit(0); } } ?> http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/results.xls?view=markup&rev=1.1 Index: phpruntests/code-samples/taskScheduler/results.xls +++ phpruntests/code-samples/taskScheduler/results.xls ÐÏࡱá <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.print.PageFormat.PMHorizontalRes</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMHorizontalRes</key> <real>300</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMOrientation</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMOrientation</key> <integer>1</integer> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMScaling</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMScaling</key> <real>1</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMVerticalRes</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMVerticalRes</key> <real>300</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMVerticalScaling</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMVerticalScaling</key> <real>1</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.subTicket.paper_info_ticket</key> <dict> <key>PMPPDPaperCodeName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>PMPPDPaperCodeName</key> <string>A4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>PMTiogaPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>PMTiogaPaperName</key> <string>iso-a4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMAdjustedPageRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMAdjustedPageRect</key> <array> <real>0.0</real> <real>0.0</real> <real>3262.5000000000005</real> <real>2329.166666666667</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMAdjustedPaperRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMAdjustedPaperRect</key> <array> <real>-75</real> <real>-75</real> <real>3433.3333333333335</real> <real>2404.166666666667</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMPaperName</key> <string>iso-a4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key> <array> <real>0.0</real> <real>0.0</real> <real>783</real> <real>559</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key> <array> <real>-18</real> <real>-18</real> <real>824</real> <real>577</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.ppd.PMPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.ppd.PMPaperName</key> <string>A4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.ticket.APIVersion</key> <string>00.20</string> <key>com.apple.print.ticket.type</key> <string>com.apple.print.PaperInfoTicket</string> </dict> <key>com.apple.print.ticket.APIVersion</key> <string>00.20</string> <key>com.apple.print.ticket.type</key> <string>com.apple.print.PageFormatTicket</string> </dict> </plist> M & ý <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.print.PageFormat.PMHorizontalRes</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMHorizontalRes</key> <real>300</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMOrientation</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMOrientation</key> <integer>1</integer> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMScaling</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMScaling</key> <real>1</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMVerticalRes</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMVerticalRes</key> <real>300</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMVerticalScaling</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMVerticalScaling</key> <real>1</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.subTicket.paper_info_ticket</key> <dict> <key>PMPPDPaperCodeName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>PMPPDPaperCodeName</key> <string>A4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>PMTiogaPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>PMTiogaPaperName</key> <string>iso-a4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMAdjustedPageRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMAdjustedPageRect</key> <array> <real>0.0</real> <real>0.0</real> <real>3262.5000000000005</real> <real>2329.166666666667</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMAdjustedPaperRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMAdjustedPaperRect</key> <array> <real>-75</real> <real>-75</real> <real>3433.3333333333335</real> <real>2404.166666666667</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMPaperName</key> <string>iso-a4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key> <array> <real>0.0</real> <real>0.0</real> <real>783</real> <real>559</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key> <array> <real>-18</real> <real>-18</real> <real>824</real> <real>577</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.ppd.PMPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.ppd.PMPaperName</key> <string>A4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.ticket.APIVersion</key> <string>00.20</string> <key>com.apple.print.ticket.type</key> <string>com.apple.print.PaperInfoTicket</string> </dict> <key>com.apple.print.ticket.APIVersion</key> <string>00.20</string> <key>com.apple.print.ticket.type</key> <string>com.apple.print.PageFormatTicket</string> </dict> </plist> M & <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.print.PageFormat.PMHorizontalRes</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMHorizontalRes</key> <real>300</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMOrientation</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMOrientation</key> <integer>1</integer> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMScaling</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMScaling</key> <real>1</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMVerticalRes</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMVerticalRes</key> <real>300</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMVerticalScaling</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMVerticalScaling</key> <real>1</real> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.subTicket.paper_info_ticket</key> <dict> <key>PMPPDPaperCodeName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>PMPPDPaperCodeName</key> <string>A4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>PMTiogaPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>PMTiogaPaperName</key> <string>iso-a4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMAdjustedPageRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMAdjustedPageRect</key> <array> <real>0.0</real> <real>0.0</real> <real>3262.5000000000005</real> <real>2329.166666666667</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PageFormat.PMAdjustedPaperRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PageFormat.PMAdjustedPaperRect</key> <array> <real>-75</real> <real>-75</real> <real>3433.3333333333335</real> <real>2404.166666666667</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMPaperName</key> <string>iso-a4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key> <array> <real>0.0</real> <real>0.0</real> <real>783</real> <real>559</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key> <array> <real>-18</real> <real>-18</real> <real>824</real> <real>577</real> </array> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.PaperInfo.ppd.PMPaperName</key> <dict> <key>com.apple.print.ticket.creator</key> <string>com.apple.jobticket</string> <key>com.apple.print.ticket.itemArray</key> <array> <dict> <key>com.apple.print.PaperInfo.ppd.PMPaperName</key> <string>A4</string> <key>com.apple.print.ticket.stateFlag</key> <integer>0</integer> </dict> </array> </dict> <key>com.apple.print.ticket.APIVersion</key> <string>00.20</string> <key>com.apple.print.ticket.type</key> <string>com.apple.print.PaperInfoTicket</string> </dict> <key>com.apple.print.ticket.APIVersion</key> <string>00.20</string> <key>com.apple.print.ticket.type</key> <string>com.apple.print.PageFormatTicket</string> </dict> </plist> M & ÿÿ ÿ cRZÖÿNsJRZÖNsF1ÿZÖþg9ÿNsùÿNsÿ F1ÿ
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php