| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 | 
							- <?php
 
- //
 
- //  FPDI - Version 1.2
 
- //
 
- //    Copyright 2004-2007 Setasign - Jan Slabon
 
- //
 
- //  Licensed under the Apache License, Version 2.0 (the "License");
 
- //  you may not use this file except in compliance with the License.
 
- //  You may obtain a copy of the License at
 
- //
 
- //      http://www.apache.org/licenses/LICENSE-2.0
 
- //
 
- //  Unless required by applicable law or agreed to in writing, software
 
- //  distributed under the License is distributed on an "AS IS" BASIS,
 
- //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
- //  See the License for the specific language governing permissions and
 
- //  limitations under the License.
 
- //
 
- if (!defined ('PDF_TYPE_NULL'))
 
-     define ('PDF_TYPE_NULL', 0);
 
- if (!defined ('PDF_TYPE_NUMERIC'))
 
-     define ('PDF_TYPE_NUMERIC', 1);
 
- if (!defined ('PDF_TYPE_TOKEN'))
 
-     define ('PDF_TYPE_TOKEN', 2);
 
- if (!defined ('PDF_TYPE_HEX'))
 
-     define ('PDF_TYPE_HEX', 3);
 
- if (!defined ('PDF_TYPE_STRING'))
 
-     define ('PDF_TYPE_STRING', 4);
 
- if (!defined ('PDF_TYPE_DICTIONARY'))
 
-     define ('PDF_TYPE_DICTIONARY', 5);
 
- if (!defined ('PDF_TYPE_ARRAY'))
 
-     define ('PDF_TYPE_ARRAY', 6);
 
- if (!defined ('PDF_TYPE_OBJDEC'))
 
-     define ('PDF_TYPE_OBJDEC', 7);
 
- if (!defined ('PDF_TYPE_OBJREF'))
 
-     define ('PDF_TYPE_OBJREF', 8);
 
- if (!defined ('PDF_TYPE_OBJECT'))
 
-     define ('PDF_TYPE_OBJECT', 9);
 
- if (!defined ('PDF_TYPE_STREAM'))
 
-     define ('PDF_TYPE_STREAM', 10);
 
- class pdf_parser {
 
- 	
 
- 	/**
 
-      * Filename
 
-      * @var string
 
-      */
 
-     var $filename;
 
-     
 
-     /**
 
-      * File resource
 
-      * @var resource
 
-      */
 
-     var $f;
 
-     
 
-     /**
 
-      * PDF Context
 
-      * @var object pdf_context-Instance
 
-      */
 
-     var $c;
 
-     
 
-     /**
 
-      * xref-Data
 
-      * @var array
 
-      */
 
-     var $xref;
 
-     /**
 
-      * root-Object
 
-      * @var array
 
-      */
 
-     var $root;
 
- 	
 
-     // mPDF 4.0 Added flag to show success on loading file
 
-     var $success;
 
-     var $errormsg;
 
-     /**
 
-      * Constructor
 
-      *
 
-      * @param string $filename  Source-Filename
 
-      */
 
- 	function pdf_parser($filename) {
 
-         $this->filename = $filename;
 
- 	  // mPDF 4.0
 
- 	  $this->success = true;
 
-         $this->f = @fopen($this->filename, "rb");
 
-         if (!$this->f) {
 
-             $this->success = false;
 
-             $this->errormsg = sprintf("Cannot open %s !", $filename);
 
- 		return false;
 
- 	  }
 
- 	// mPDF 5.0 Removed pass by reference =&
 
-         $this->c = new pdf_context($this->f);
 
-         // Read xref-Data
 
- 	  $offset = $this->pdf_find_xref();
 
-         if ($offset===false) {
 
-             $this->success = false;
 
-             $this->errormsg = sprintf("Cannot open %s !", $filename);
 
- 		return false;
 
- 	  }
 
-         $this->pdf_read_xref($this->xref, $offset);
 
-         if ($this->success == false) { return false; }
 
-         // Check for Encryption
 
-         $this->getEncryption();
 
-         if ($this->success == false) { return false; }
 
-         // Read root
 
-         $this->pdf_read_root();
 
-         if ($this->success == false) { return false; }
 
-     }
 
-     
 
-     /**
 
-      * Close the opened file
 
-      */
 
-     function closeFile() {
 
-     	if (isset($this->f)) {
 
-     	    fclose($this->f);	
 
-     		unset($this->f);
 
-     	}	
 
-     }
 
-     
 
-       /**
 
-      * Print Error and die
 
-      *
 
-      * @param string $msg  Error-Message
 
-      */
 
-     function error($msg) {
 
-     	die("<b>PDF-Parser Error:</b> ".$msg);	
 
-     }
 
-   
 
-     /**
 
-      * Check Trailer for Encryption
 
-      */
 
-     function getEncryption() {
 
-         if (isset($this->xref['trailer'][1]['/Encrypt'])) {
 
- 	 	// mPDF 4.0
 
-            	$this->success = false;
 
-             $this->errormsg = sprintf("File is encrypted!");
 
- 		return false;
 
-         }
 
-     }
 
-     
 
- 	/**
 
-      * Find/Return /Root
 
-      *
 
-      * @return array
 
-      */
 
-     function pdf_find_root() {
 
-         if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) {
 
- 	 	// mPDF 4.0
 
-            	$this->success = false;
 
-             $this->errormsg = sprintf("Wrong Type of Root-Element! Must be an indirect reference");
 
- 		return false;
 
-         }
 
-         return $this->xref['trailer'][1]['/Root'];
 
-     }
 
-     /**
 
-      * Read the /Root
 
-      */
 
-     function pdf_read_root() {
 
-         // read root
 
- 	  $root = $this->pdf_find_root();
 
-         if ($root ===false) {
 
-             $this->success = false;
 
- 		return false;
 
- 	  }
 
-         $this->root = $this->pdf_resolve_object($this->c, $root);
 
-     }
 
-     
 
-     /**
 
-      * Find the xref-Table
 
-      */
 
-     function pdf_find_xref() {
 
-        	fseek ($this->f, -min(filesize($this->filename),1500), SEEK_END);
 
-         $data = fread($this->f, 1500);
 
-         
 
-         $pos = strlen($data) - strpos(strrev($data), strrev('startxref')); 
 
-         $data = substr($data, $pos);
 
-         
 
-         if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) {
 
- 	 	// mPDF 4.0
 
-            	$this->success = false;
 
-             $this->errormsg = sprintf("Unable to find pointer to xref table");
 
- 		return false;
 
-     	}
 
-     	return (int) $matches[1];
 
-     }
 
-     /**
 
-      * Read xref-table
 
-      *
 
-      * @param array $result Array of xref-table
 
-      * @param integer $offset of xref-table
 
-      * @param integer $start start-position in xref-table
 
-      * @param integer $end end-position in xref-table
 
-      */
 
-     function pdf_read_xref(&$result, $offset, $start = null, $end = null) {
 
-         if (is_null ($start) || is_null ($end)) {
 
- 		fseek($this->f, $o_pos = $offset);
 
-             $data = trim(fgets($this->f,1024));
 
-             if (strlen($data) == 0) 
 
-                 $data = trim(fgets($this->f,1024));
 
-             if ($data !== 'xref') {
 
-             	fseek($this->f, $o_pos);
 
-             	$data = trim(_fgets($this->f, true));
 
-             	if ($data !== 'xref') {
 
-             	    if (preg_match('/(.*xref)(.*)/m', $data, $m)) { // xref 0 128 - in one line
 
-                         fseek($this->f, $o_pos+strlen($m[1]));            	        
 
-             	    } elseif (preg_match('/(x|r|e|f)+/', $data, $m)) { // correct invalid xref-pointer
 
-             	        $tmpOffset = $offset-4+strlen($m[0]);
 
-             	        $this->pdf_read_xref($result, $tmpOffset, $start, $end);
 
-             	        return;
 
-                     } else {
 
- 	 			// mPDF 4.0
 
-            			$this->success = false;
 
-             		$this->errormsg = sprintf("Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings'");
 
- 				return;
 
-             	    }
 
-             	}
 
-     		}
 
-     		$o_pos = ftell($this->f);
 
-     	    $data = explode(' ', trim(fgets($this->f,1024)));
 
- 			if (count($data) != 2) {
 
-     	        fseek($this->f, $o_pos);
 
-     	        $data = explode(' ', trim(_fgets($this->f, true)));
 
- 			
 
-             	if (count($data) != 2) {
 
-             	    if (count($data) > 2) { // no lineending
 
-             	        $n_pos = $o_pos+strlen($data[0])+strlen($data[1])+2;
 
-             	        fseek($this->f, $n_pos);
 
-             	    } else {
 
- 	 			// mPDF 4.0
 
-            			$this->success = false;
 
-             		$this->errormsg = sprintf("Unexpected header in xref table");
 
- 				return;
 
-             	    }
 
-             	}
 
-             }
 
-             $start = $data[0];
 
-             $end = $start + $data[1];
 
-         }
 
-         if (!isset($result['xref_location'])) {
 
-             $result['xref_location'] = $offset;
 
-     	}
 
-     	if (!isset($result['max_object']) || $end > $result['max_object']) {
 
-     	    $result['max_object'] = $end;
 
-     	}
 
-     	for (; $start < $end; $start++) {
 
-     		$data = ltrim(fread($this->f, 20)); // Spezifications says: 20 bytes including newlines
 
-     		$offset = substr($data, 0, 10);
 
-     		$generation = substr($data, 11, 5);
 
-     	    if (!isset ($result['xref'][$start][(int) $generation])) {
 
-     	    	$result['xref'][$start][(int) $generation] = (int) $offset;
 
-     	    }
 
-     	}
 
-     	$o_pos = ftell($this->f);
 
-         $data = fgets($this->f,1024);
 
- 		if (strlen(trim($data)) == 0) 
 
- 		    $data = fgets($this->f, 1024);
 
-         if (preg_match("/trailer/",$data)) {
 
-             if (preg_match("/(.*trailer[ \n\r]*)/",$data,$m)) {
 
-             	fseek($this->f, $o_pos+strlen($m[1]));
 
-     		}
 
- 			// mPDF 5.0 Removed pass by reference =&
 
- 			$c = new pdf_context($this->f);
 
-     	    $trailer = $this->pdf_read_value($c);
 
-     	    
 
-     	    if (isset($trailer[1]['/Prev'])) {
 
-     	    	$this->pdf_read_xref($result, $trailer[1]['/Prev'][1]);
 
-     		    $result['trailer'][1] = array_merge($result['trailer'][1], $trailer[1]);
 
-     	    } else {
 
-     	        $result['trailer'] = $trailer;
 
-             }
 
-     	} else {
 
-     	    $data = explode(' ', trim($data));
 
-             
 
-     		if (count($data) != 2) {
 
-             	fseek($this->f, $o_pos);
 
-         		$data = explode(' ', trim (_fgets ($this->f, true)));
 
-         		if (count($data) != 2) {
 
- 	 			// mPDF 4.0
 
-            			$this->success = false;
 
-             		$this->errormsg = sprintf("Unexpected data in xref table");
 
- 				return;
 
-         		}
 
- 		    }
 
- 		    
 
- 		    $this->pdf_read_xref($result, null, (int) $data[0], (int) $data[0] + (int) $data[1]);
 
-     	}
 
-     }
 
-     /**
 
-      * Reads an Value
 
-      *
 
-      * @param object $c pdf_context
 
-      * @param string $token a Token
 
-      * @return mixed
 
-      */
 
-     function pdf_read_value(&$c, $token = null) {
 
-     	if (is_null($token)) {
 
-     	    $token = $this->pdf_read_token($c);
 
-     	}
 
-     	
 
-         if ($token === false) {
 
-     	    return false;
 
-     	}
 
-        	switch ($token) {
 
-             case	'<':
 
-     			// This is a hex string.
 
-     			// Read the value, then the terminator
 
-                 $pos = $c->offset;
 
-     			while(1) {
 
-                     $match = strpos ($c->buffer, '>', $pos);
 
- 				
 
-     				// If you can't find it, try
 
-     				// reading more data from the stream
 
-     				if ($match === false) {
 
-     					if (!$c->increase_length()) {
 
-     						return false;
 
-     					} else {
 
-                         	continue;
 
-                     	}
 
-     				}
 
-     				$result = substr ($c->buffer, $c->offset, $match - $c->offset);
 
-     				$c->offset = $match+1;
 
-     				
 
-     				return array (PDF_TYPE_HEX, $result);
 
-                 }
 
-                 
 
-                 break;
 
-     		case	'<<':
 
-     			// This is a dictionary.
 
-     			$result = array();
 
-     			// Recurse into this function until we reach
 
-     			// the end of the dictionary.
 
-     			while (($key = $this->pdf_read_token($c)) !== '>>') {
 
-     				if ($key === false) {
 
-     					return false;
 
-     				}
 
- 					
 
-     				if (($value =   $this->pdf_read_value($c)) === false) {
 
-     					return false;
 
-     				}
 
-                     $result[$key] = $value;
 
-     			}
 
- 				
 
-     			return array (PDF_TYPE_DICTIONARY, $result);
 
-     		case	'[':
 
-     			// This is an array.
 
-     			$result = array();
 
-     			// Recurse into this function until we reach
 
-     			// the end of the array.
 
-     			while (($token = $this->pdf_read_token($c)) !== ']') {
 
-                     if ($token === false) {
 
-     					return false;
 
-     				}
 
- 					
 
-     				if (($value = $this->pdf_read_value($c, $token)) === false) {
 
-                         return false;
 
-     				}
 
- 					
 
-     				$result[] = $value;
 
-     			}
 
-     			
 
-                 return array (PDF_TYPE_ARRAY, $result);
 
-     		case	'('		:
 
-                 // This is a string
 
-     			$pos = $c->offset;
 
-     			while(1) {
 
-                     // Start by finding the next closed
 
-     				// parenthesis
 
-     				$match = strpos ($c->buffer, ')', $pos);
 
-     				// If you can't find it, try
 
-     				// reading more data from the stream
 
-     				if ($match === false) {
 
-     					if (!$c->increase_length()) {
 
-                             return false;
 
-     					} else {
 
-                             continue;
 
-                         }
 
-     				}
 
-     				// Make sure that there is no backslash
 
-     				// before the parenthesis. If there is,
 
-     				// move on. Otherwise, return the string.
 
-                     $esc = preg_match('/([\\\\]+)$/', $tmpresult = substr($c->buffer, $c->offset, $match - $c->offset), $m);
 
-                     
 
-                     if ($esc === 0 || strlen($m[1]) % 2 == 0) {
 
-     				    $result = $tmpresult;
 
-                         $c->offset = $match + 1;
 
-                         return array (PDF_TYPE_STRING, $result);
 
-     				} else {
 
-     					$pos = $match + 1;
 
-     					if ($pos > $c->offset + $c->length) {
 
-     						$c->increase_length();
 
-     					}
 
-     				}    				
 
-                 }
 
-             case "stream":
 
-             	$o_pos = ftell($c->file)-strlen($c->buffer);
 
- 		        $o_offset = $c->offset;
 
- 		        
 
- 		        $c->reset($startpos = $o_pos + $o_offset);
 
- 		        
 
- 		        $e = 0; // ensure line breaks in front of the stream
 
- 		        if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13))
 
- 		        	$e++;
 
- 		        if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10))
 
- 		        	$e++;
 
- 		        
 
- 		        if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) {
 
- 				// mPDF 5.0 Removed pass by reference =&
 
- 		        	$tmp_c = new pdf_context($this->f);
 
- 		        	$tmp_length = $this->pdf_resolve_object($tmp_c,$this->actual_obj[1][1]['/Length']);
 
- 		        	$length = $tmp_length[1][1];
 
- 		        } else {
 
- 		        	$length = $this->actual_obj[1][1]['/Length'][1];	
 
- 		        }
 
- 		        
 
- 		        if ($length > 0) {
 
-     		        $c->reset($startpos+$e,$length);
 
-     		        $v = $c->buffer;
 
- 		        } else {
 
- 		            $v = '';   
 
- 		        }
 
- 		        $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream")
 
- 		        
 
- 		        return array(PDF_TYPE_STREAM, $v);
 
- 		        
 
-     		default	:
 
-             	if (is_numeric ($token)) {
 
-                     // A numeric token. Make sure that
 
-     				// it is not part of something else.
 
-     				if (($tok2 = $this->pdf_read_token ($c)) !== false) {
 
-                         if (is_numeric ($tok2)) {
 
-     						// Two numeric tokens in a row.
 
-     						// In this case, we're probably in
 
-     						// front of either an object reference
 
-     						// or an object specification.
 
-     						// Determine the case and return the data
 
-     						if (($tok3 = $this->pdf_read_token ($c)) !== false) {
 
-                                 switch ($tok3) {
 
-     								case	'obj'	:
 
-                                         return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2);
 
-     								case	'R'		:
 
-     									return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2);
 
-     							}
 
-     							// If we get to this point, that numeric value up
 
-     							// there was just a numeric value. Push the extra
 
-     							// tokens back into the stack and return the value.
 
-     							array_push ($c->stack, $tok3);
 
-     						}
 
-     					}
 
-     					array_push ($c->stack, $tok2);
 
-     				}
 
-     				return array (PDF_TYPE_NUMERIC, $token);
 
-     			} else {
 
-                     // Just a token. Return it.
 
-     				return array (PDF_TYPE_TOKEN, $token);
 
-     			}
 
-          }
 
-     }
 
-     
 
-     /**
 
-      * Resolve an object
 
-      *
 
-      * @param object $c pdf_context
 
-      * @param array $obj_spec The object-data
 
-      * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para
 
-      */
 
-     function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) {
 
-         // Exit if we get invalid data
 
-     	if (!is_array($obj_spec)) {
 
-             return false;
 
-     	}
 
-     	if ($obj_spec[0] == PDF_TYPE_OBJREF) {
 
-     		// This is a reference, resolve it
 
-     		if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) {
 
-     			// Save current file position
 
-     			// This is needed if you want to resolve
 
-     			// references while you're reading another object
 
-     			// (e.g.: if you need to determine the length
 
-     			// of a stream)
 
-     			$old_pos = ftell($c->file);
 
-     			// Reposition the file pointer and
 
-     			// load the object header.
 
- 				
 
-     			$c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]);
 
-     			$header = $this->pdf_read_value($c,null,true);
 
-     			if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) {
 
- 	 			// mPDF 4.0
 
-            			$this->success = false;
 
-             		$this->errormsg = sprintf("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location");
 
- 				return false;
 
-     			}
 
-     			// If we're being asked to store all the information
 
-     			// about the object, we add the object ID and generation
 
-     			// number for later use
 
- 				$this->actual_obj =& $result;
 
-     			if ($encapsulate) {
 
-     				$result = array (
 
-     					PDF_TYPE_OBJECT,
 
-     					'obj' => $obj_spec[1],
 
-     					'gen' => $obj_spec[2]
 
-     				);
 
-     			} else {
 
-     				$result = array();
 
-     			}
 
-     			// Now simply read the object data until
 
-     			// we encounter an end-of-object marker
 
-     			while(1) {
 
-                     $value = $this->pdf_read_value($c);
 
- 					if ($value === false || count($result) > 4) {
 
- 						// in this case the parser coudn't find an endobj so we break here
 
- 						break;
 
-     				}
 
-     				if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') {
 
-     					break;
 
-     				}
 
-                     $result[] = $value;
 
-     			}
 
-     			$c->reset($old_pos);
 
-                 if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) {
 
-                     $result[0] = PDF_TYPE_STREAM;
 
-                 }
 
-     			return $result;
 
-     		}
 
-     	} else {
 
-     		return $obj_spec;
 
-     	}
 
-     }
 
-     
 
-     
 
-     /**
 
-      * Reads a token from the file
 
-      *
 
-      * @param object $c pdf_context
 
-      * @return mixed
 
-      */
 
-     function pdf_read_token(&$c)
 
-     {
 
-     	// If there is a token available
 
-     	// on the stack, pop it out and
 
-     	// return it.
 
-     	if (count($c->stack)) {
 
-     		return array_pop($c->stack);
 
-     	}
 
-     	// Strip away any whitespace
 
-     	do {
 
-     		if (!$c->ensure_content()) {
 
-     			return false;
 
-     		}
 
-     		$c->offset += _strspn($c->buffer, " \n\r\t", $c->offset);
 
-     	} while ($c->offset >= $c->length - 1);
 
-     	// Get the first character in the stream
 
-     	$char = $c->buffer[$c->offset++];
 
-     	switch ($char) {
 
-     		case '['	:
 
-     		case ']'	:
 
-     		case '('	:
 
-     		case ')'	:
 
-     			// This is either an array or literal string
 
-     			// delimiter, Return it
 
-     			return $char;
 
-     		case '<'	:
 
-     		case '>'	:
 
-     			// This could either be a hex string or
 
-     			// dictionary delimiter. Determine the
 
-     			// appropriate case and return the token
 
-     			if ($c->buffer[$c->offset] == $char) {
 
-     				if (!$c->ensure_content()) {
 
-     				    return false;
 
-     				}
 
-     				$c->offset++;
 
-     				return $char . $char;
 
-     			} else {
 
-     				return $char;
 
-     			}
 
-     		default		:
 
-     			// This is "another" type of token (probably
 
-     			// a dictionary entry or a numeric value)
 
-     			// Find the end and return it.
 
-     			if (!$c->ensure_content()) {
 
-     				return false;
 
-     			}
 
-     			while(1) {
 
-     				// Determine the length of the token
 
-     				$pos = _strcspn($c->buffer, " []<>()\r\n\t/", $c->offset);
 
-     				if ($c->offset + $pos <= $c->length - 1) {
 
-     					break;
 
-     				} else {
 
-     					// If the script reaches this point,
 
-     					// the token may span beyond the end
 
-     					// of the current buffer. Therefore,
 
-     					// we increase the size of the buffer
 
-     					// and try again--just to be safe.
 
-     					$c->increase_length();
 
-     				}
 
-     			}
 
-     			$result = substr($c->buffer, $c->offset - 1, $pos + 1);
 
-     			$c->offset += $pos;
 
-     			return $result;
 
-     	}
 
-     }
 
- 	
 
- }
 
- ?>
 
 
  |