def read(self, callback, grpos_range, frames=None):
        if grpos_range:
            # here we only handle the case of data shrinking from the
            # left / earlier side...
            end_grpos = self._grpos + grpos_range
            pos = self._pos
            grpos = self._grpos
            while 1:
                idx = pos - self._s.data_offset
                if idx < 0:
                    pos -= idx
                    idx = 0
                try:
                    f = self._s.data[idx]
                except __HOLE__:
                    # we're behind the last frame -> no read
                    break
                grpos = f[0]
                if grpos >= end_grpos:
                    grpos = end_grpos
                    break
                callback(*f)
                pos += 1
            self._pos = pos
            self._grpos = grpos
        elif frames:
            pos = self._pos
            grpos = self._grpos
            while 1:
                idx = pos - self._s.data_offset
                if idx < 0:
                    pos -= idx
                    frames += idx
                if frames < 1:
                    break
                try:
                    f = self._s.data[idx]
                except IndexError:
                    # we're behind the last frame -> no more read
                    break
                grpos = f[0]
                callback(*f)
                pos += 1
                frames -= 1
            self._pos = pos
            self._grpos = grpos

        # if HAVE_TASKS:
        #     t = tasks.CompTask()
        #     return t, t.run()

        return None, defer.succeed(None)
dataset/ETHPy150Open arkadini/twimp/twimp/server/inmemory.py/IMStream.read