Annotation of embedaddon/php/ext/standard/tests/file/userstreams.phpt, revision 1.1
1.1 ! misho 1: --TEST--
! 2: User-space streams
! 3: --FILE--
! 4: <?php
! 5: # vim600:syn=php:
! 6:
! 7: /* This is a fairly aggressive test that looks at
! 8: * user streams and also gives the seek/gets/buffer
! 9: * layer of streams a thorough testing */
! 10:
! 11: $lyrics = <<<EOD
! 12: ...and the road becomes my bride
! 13: I have stripped of all but pride
! 14: so in her I do confide
! 15: and she keeps me satisfied
! 16: gives me all I need
! 17: ...and with dust in throat I crave
! 18: to the game you stay a slave
! 19: rover wanderer
! 20: nomad vagabond
! 21: call me what you will
! 22: But Ill take my time anywhere
! 23: Free to speak my mind anywhere
! 24: and Ill redefine anywhere
! 25: Anywhere I roam
! 26: Where I lay my head is home
! 27: ...and the earth becomes my throne
! 28: I adapt to the unknown
! 29: under wandering stars Ive grown
! 30: by myself but not alone
! 31: I ask no one
! 32: ...and my ties are severed clean
! 33: the less I have the more I gain
! 34: off the beaten path I reign
! 35: rover wanderer
! 36: nomad vagabond
! 37: call me what you will
! 38: But Ill take my time anywhere
! 39: Free to speak my mind anywhere
! 40: and Ill never mind anywhere
! 41: Anywhere I roam
! 42: Where I lay my head is home
! 43: But Ill take my time anywhere
! 44: Free to speak my mind anywhere
! 45: and Ill take my find anywhere
! 46: Anywhere I roam
! 47: Where I lay my head is home
! 48: carved upon my stone
! 49: my body lie but still I roam
! 50: Wherever I may roam.
! 51:
! 52: Wherever I May Roam
! 53:
! 54: EOD;
! 55:
! 56: /* repeat the data a few times so that it grows larger than
! 57: * the default cache chunk size and that we have something
! 58: * to seek around... */
! 59: $DATA = "";
! 60: for ($i = 0; $i < 30; $i++) {
! 61: if ($i % 2 == 0)
! 62: $DATA .= str_rot13($lyrics);
! 63: else
! 64: $DATA .= $lyrics;
! 65: }
! 66:
! 67: /* store the data in a regular file so that we can compare
! 68: * the results */
! 69: $tf = tmpfile();
! 70: fwrite($tf, (binary)$DATA);
! 71: $n = ftell($tf);
! 72: rewind($tf) or die("failed to rewind tmp file!");
! 73: if (ftell($tf) != 0)
! 74: die("tmpfile is not at start!");
! 75: $DATALEN = strlen($DATA);
! 76: if ($n != $DATALEN)
! 77: die("tmpfile stored $n bytes; should be $DATALEN!");
! 78:
! 79: class uselessstream
! 80: {
! 81: }
! 82:
! 83: class mystream
! 84: {
! 85: public $path;
! 86: public $mode;
! 87: public $options;
! 88:
! 89: public $position;
! 90: public $varname;
! 91:
! 92: function stream_open($path, $mode, $options, &$opened_path)
! 93: {
! 94: $this->path = $path;
! 95: $this->mode = $mode;
! 96: $this->options = $options;
! 97:
! 98: $split = parse_url($path);
! 99: $this->varname = $split["host"];
! 100:
! 101: if (strchr($mode, 'a'))
! 102: $this->position = strlen($GLOBALS[$this->varname]);
! 103: else
! 104: $this->position = 0;
! 105:
! 106: return true;
! 107: }
! 108:
! 109: function stream_read($count)
! 110: {
! 111: $ret = substr($GLOBALS[$this->varname], $this->position, $count);
! 112: $this->position += strlen($ret);
! 113: return $ret;
! 114: }
! 115:
! 116: function stream_tell()
! 117: {
! 118: return $this->position;
! 119: }
! 120:
! 121: function stream_eof()
! 122: {
! 123: return $this->position >= strlen($GLOBALS[$this->varname]);
! 124: }
! 125:
! 126: function stream_seek($offset, $whence)
! 127: {
! 128: switch($whence) {
! 129: case SEEK_SET:
! 130: if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) {
! 131: $this->position = $offset;
! 132: return true;
! 133: } else {
! 134: return false;
! 135: }
! 136: break;
! 137: case SEEK_CUR:
! 138: if ($offset >= 0) {
! 139: $this->position += $offset;
! 140: return true;
! 141: } else {
! 142: return false;
! 143: }
! 144: break;
! 145: case SEEK_END:
! 146: if (strlen($GLOBALS[$this->varname]) + $offset >= 0) {
! 147: $this->position = strlen($GLOBALS[$this->varname]) + $offset;
! 148: return true;
! 149: } else {
! 150: return false;
! 151: }
! 152: break;
! 153: default:
! 154: return false;
! 155: }
! 156: }
! 157:
! 158: }
! 159:
! 160: if (@stream_wrapper_register("bogus", "class_not_exist")) {
! 161: die("Registered a non-existant class!!!???");
! 162: }
! 163: echo "Not Registered\n";
! 164:
! 165: if (!stream_wrapper_register("test", "mystream")) {
! 166: die("test wrapper registration failed");
! 167: }
! 168: echo "Registered\n";
! 169:
! 170: if (!stream_wrapper_register("bogon", "uselessstream")) {
! 171: die("bogon wrapper registration failed");
! 172: }
! 173: echo "Registered\n";
! 174:
! 175: $b = @fopen("bogon://url", "rb");
! 176: if (is_resource($b)) {
! 177: die("Opened a bogon??");
! 178: }
! 179:
! 180: $fp = fopen("test://DATA", "rb");
! 181: if (!$fp || !is_resource($fp)) {
! 182: die("Failed to open resource");
! 183: }
! 184:
! 185: /* some default seeks that will cause buffer/cache misses */
! 186: $seeks = array(
! 187: array(SEEK_SET, 0, 0),
! 188: array(SEEK_CUR, 8450, 8450),
! 189: array(SEEK_CUR, -7904, 546),
! 190: array(SEEK_CUR, 12456, 13002),
! 191:
! 192: /* end up at BOF so that randomly generated seek offsets
! 193: * below will know where they are supposed to be */
! 194: array(SEEK_SET, 0, 0)
! 195: );
! 196:
! 197: $whence_map = array(
! 198: SEEK_CUR,
! 199: SEEK_SET,
! 200: SEEK_END
! 201: );
! 202: $whence_names = array(
! 203: SEEK_CUR => "SEEK_CUR",
! 204: SEEK_SET => "SEEK_SET",
! 205: SEEK_END => "SEEK_END"
! 206: );
! 207:
! 208: /* generate some random seek offsets */
! 209: $position = 0;
! 210: for ($i = 0; $i < 256; $i++) {
! 211: $whence = $whence_map[array_rand($whence_map, 1)];
! 212: switch($whence) {
! 213: case SEEK_SET:
! 214: $offset = rand(0, $DATALEN - 1);
! 215: $position = $offset;
! 216: break;
! 217: case SEEK_END:
! 218: $offset = -rand(0, $DATALEN - 1);
! 219: $position = $DATALEN + $offset;
! 220: break;
! 221: case SEEK_CUR:
! 222: $offset = rand(0, $DATALEN - 1);
! 223: $offset -= $position;
! 224: $position += $offset;
! 225: break;
! 226: }
! 227:
! 228: $seeks[] = array($whence, $offset, $position);
! 229: }
! 230:
! 231: /* we compare the results of fgets using differing line lengths to
! 232: * test the fgets layer also */
! 233: $line_lengths = array(1024, 256, 64, 16);
! 234: $fail_count = 0;
! 235:
! 236: ob_start();
! 237: foreach($line_lengths as $line_length) {
! 238: /* now compare the real stream with the user stream */
! 239: $j = 0;
! 240: rewind($tf);
! 241: rewind($fp);
! 242: foreach($seeks as $seekdata) {
! 243: list($whence, $offset, $position) = $seekdata;
! 244:
! 245: $rpb = ftell($tf);
! 246: $rr = (int)fseek($tf, $offset, $whence);
! 247: $rpa = ftell($tf);
! 248: $rline = fgets($tf, $line_length);
! 249: (int)fseek($tf, - strlen($rline), SEEK_CUR);
! 250:
! 251: $upb = ftell($fp);
! 252: $ur = (int)fseek($fp, $offset, $whence);
! 253: $upa = ftell($fp);
! 254: $uline = fgets($fp, $line_length);
! 255: (int)fseek($fp, - strlen($uline), SEEK_CUR);
! 256:
! 257: printf("\n--[%d] whence=%s offset=%d line_length=%d position_should_be=%d --\n",
! 258: $j, $whence_names[$whence], $offset, $line_length, $position);
! 259: printf("REAL: pos=(%d,%d,%d) ret=%d line[%d]=`%s'\n", $rpb, $rpa, ftell($tf), $rr, strlen($rline), $rline);
! 260: printf("USER: pos=(%d,%d,%d) ret=%d line[%d]=`%s'\n", $upb, $upa, ftell($fp), $ur, strlen($uline), $uline);
! 261:
! 262: if ($rr != $ur || $rline != $uline || $rpa != $position || $upa != $position) {
! 263: $fail_count++;
! 264: echo "###################################### FAIL!\n";
! 265: $dat = stream_get_meta_data($fp);
! 266: var_dump($dat);
! 267: break;
! 268: }
! 269:
! 270: $j++;
! 271: }
! 272: if ($fail_count)
! 273: break;
! 274: }
! 275:
! 276: if ($fail_count == 0) {
! 277: ob_end_clean();
! 278: echo "SEEK: OK\n";
! 279: } else {
! 280: echo "SEEK: FAIL\n";
! 281: ob_end_flush();
! 282: }
! 283:
! 284: $fail_count = 0;
! 285:
! 286: fseek($fp, $DATALEN / 2, SEEK_SET);
! 287: fseek($tf, $DATALEN / 2, SEEK_SET);
! 288:
! 289: if (ftell($fp) != ftell($tf)) {
! 290: echo "SEEK: positions do not match!\n";
! 291: }
! 292:
! 293: $n = 0;
! 294: while(!feof($fp)) {
! 295: $uline = fgets($fp, 1024);
! 296: $rline = fgets($tf, 1024);
! 297:
! 298: if ($uline != $rline) {
! 299: echo "FGETS: FAIL\niter=$n user=$uline [pos=" . ftell($fp) . "]\nreal=$rline [pos=" . ftell($tf) . "]\n";
! 300: $fail_count++;
! 301: break;
! 302: }
! 303: }
! 304:
! 305: if ($fail_count == 0) {
! 306: echo "FGETS: OK\n";
! 307: }
! 308:
! 309: /* One final test to see if the position is respected when opened for append */
! 310: $fp = fopen("test://lyrics", "a+");
! 311: rewind($fp);
! 312: var_dump(ftell($fp));
! 313: $data = fgets($fp);
! 314: fclose($fp);
! 315: echo $data . "\n";
! 316:
! 317: ?>
! 318: --EXPECT--
! 319: Not Registered
! 320: Registered
! 321: Registered
! 322: SEEK: OK
! 323: FGETS: OK
! 324: int(0)
! 325: ...and the road becomes my bride
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>