Annotation of embedaddon/php/ext/standard/tests/file/userstreams.phpt, revision 1.1.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>