--TEST-- User-space streams --FILE-- path = $path; $this->mode = $mode; $this->options = $options; $split = parse_url($path); $this->varname = $split["host"]; if (strchr($mode, 'a')) $this->position = strlen($GLOBALS[$this->varname]); else $this->position = 0; return true; } function stream_read($count) { $ret = substr($GLOBALS[$this->varname], $this->position, $count); $this->position += strlen($ret); return $ret; } function stream_tell() { return $this->position; } function stream_eof() { return $this->position >= strlen($GLOBALS[$this->varname]); } function stream_seek($offset, $whence) { switch($whence) { case SEEK_SET: if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) { $this->position = $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >= 0) { $this->position += $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($GLOBALS[$this->varname]) + $offset >= 0) { $this->position = strlen($GLOBALS[$this->varname]) + $offset; return true; } else { return false; } break; default: return false; } } } if (@stream_wrapper_register("bogus", "class_not_exist")) { die("Registered a non-existant class!!!???"); } echo "Not Registered\n"; if (!stream_wrapper_register("test", "mystream")) { die("test wrapper registration failed"); } echo "Registered\n"; if (!stream_wrapper_register("bogon", "uselessstream")) { die("bogon wrapper registration failed"); } echo "Registered\n"; $b = @fopen("bogon://url", "rb"); if (is_resource($b)) { die("Opened a bogon??"); } $fp = fopen("test://DATA", "rb"); if (!$fp || !is_resource($fp)) { die("Failed to open resource"); } /* some default seeks that will cause buffer/cache misses */ $seeks = array( array(SEEK_SET, 0, 0), array(SEEK_CUR, 8450, 8450), array(SEEK_CUR, -7904, 546), array(SEEK_CUR, 12456, 13002), /* end up at BOF so that randomly generated seek offsets * below will know where they are supposed to be */ array(SEEK_SET, 0, 0) ); $whence_map = array( SEEK_CUR, SEEK_SET, SEEK_END ); $whence_names = array( SEEK_CUR => "SEEK_CUR", SEEK_SET => "SEEK_SET", SEEK_END => "SEEK_END" ); /* generate some random seek offsets */ $position = 0; for ($i = 0; $i < 256; $i++) { $whence = $whence_map[array_rand($whence_map, 1)]; switch($whence) { case SEEK_SET: $offset = rand(0, $DATALEN - 1); $position = $offset; break; case SEEK_END: $offset = -rand(0, $DATALEN - 1); $position = $DATALEN + $offset; break; case SEEK_CUR: $offset = rand(0, $DATALEN - 1); $offset -= $position; $position += $offset; break; } $seeks[] = array($whence, $offset, $position); } /* we compare the results of fgets using differing line lengths to * test the fgets layer also */ $line_lengths = array(1024, 256, 64, 16); $fail_count = 0; ob_start(); foreach($line_lengths as $line_length) { /* now compare the real stream with the user stream */ $j = 0; rewind($tf); rewind($fp); foreach($seeks as $seekdata) { list($whence, $offset, $position) = $seekdata; $rpb = ftell($tf); $rr = (int)fseek($tf, $offset, $whence); $rpa = ftell($tf); $rline = fgets($tf, $line_length); (int)fseek($tf, - strlen($rline), SEEK_CUR); $upb = ftell($fp); $ur = (int)fseek($fp, $offset, $whence); $upa = ftell($fp); $uline = fgets($fp, $line_length); (int)fseek($fp, - strlen($uline), SEEK_CUR); printf("\n--[%d] whence=%s offset=%d line_length=%d position_should_be=%d --\n", $j, $whence_names[$whence], $offset, $line_length, $position); printf("REAL: pos=(%d,%d,%d) ret=%d line[%d]=`%s'\n", $rpb, $rpa, ftell($tf), $rr, strlen($rline), $rline); printf("USER: pos=(%d,%d,%d) ret=%d line[%d]=`%s'\n", $upb, $upa, ftell($fp), $ur, strlen($uline), $uline); if ($rr != $ur || $rline != $uline || $rpa != $position || $upa != $position) { $fail_count++; echo "###################################### FAIL!\n"; $dat = stream_get_meta_data($fp); var_dump($dat); break; } $j++; } if ($fail_count) break; } if ($fail_count == 0) { ob_end_clean(); echo "SEEK: OK\n"; } else { echo "SEEK: FAIL\n"; ob_end_flush(); } $fail_count = 0; fseek($fp, $DATALEN / 2, SEEK_SET); fseek($tf, $DATALEN / 2, SEEK_SET); if (ftell($fp) != ftell($tf)) { echo "SEEK: positions do not match!\n"; } $n = 0; while(!feof($fp)) { $uline = fgets($fp, 1024); $rline = fgets($tf, 1024); if ($uline != $rline) { echo "FGETS: FAIL\niter=$n user=$uline [pos=" . ftell($fp) . "]\nreal=$rline [pos=" . ftell($tf) . "]\n"; $fail_count++; break; } } if ($fail_count == 0) { echo "FGETS: OK\n"; } /* One final test to see if the position is respected when opened for append */ $fp = fopen("test://lyrics", "a+"); rewind($fp); var_dump(ftell($fp)); $data = fgets($fp); fclose($fp); echo $data . "\n"; ?> --EXPECT-- Not Registered Registered Registered SEEK: OK FGETS: OK int(0) ...and the road becomes my bride