~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/memory.py

  • Committer: Alexander Belchenko
  • Date: 2006-07-30 16:43:12 UTC
  • mto: (1711.2.111 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1906.
  • Revision ID: bialix@ukr.net-20060730164312-b025fd3ff0cee59e
rename  gpl.txt => COPYING.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
so this is primarily useful for testing.
21
21
"""
22
22
 
 
23
from copy import copy
23
24
import os
24
25
import errno
25
26
import re
27
28
from cStringIO import StringIO
28
29
import warnings
29
30
 
30
 
from bzrlib.errors import (
31
 
    FileExists,
32
 
    LockError,
33
 
    InProcessTransport,
34
 
    NoSuchFile,
35
 
    TransportError,
36
 
    )
 
31
from bzrlib.errors import TransportError, NoSuchFile, FileExists, LockError
37
32
from bzrlib.trace import mutter
38
 
from bzrlib.transport import (
39
 
    LateReadError,
40
 
    register_transport,
41
 
    Server,
42
 
    Transport,
43
 
    )
 
33
from bzrlib.transport import (Transport, register_transport, Server)
44
34
import bzrlib.urlutils as urlutils
45
35
 
46
36
 
69
59
        if url[-1] != '/':
70
60
            url = url + '/'
71
61
        super(MemoryTransport, self).__init__(url)
72
 
        split = url.find(':') + 3
73
 
        self._scheme = url[:split]
74
 
        self._cwd = url[split:]
 
62
        self._cwd = url[url.find(':') + 3:]
75
63
        # dictionaries from absolute path to file mode
76
64
        self._dirs = {'/':None}
77
65
        self._files = {}
79
67
 
80
68
    def clone(self, offset=None):
81
69
        """See Transport.clone()."""
82
 
        path = self._combine_paths(self._cwd, offset)
83
 
        if len(path) == 0 or path[-1] != '/':
84
 
            path += '/'
85
 
        url = self._scheme + path
 
70
        if offset is None or offset == '':
 
71
            return copy(self)
 
72
        segments = offset.split('/')
 
73
        cwdsegments = self._cwd.split('/')[:-1]
 
74
        while len(segments):
 
75
            segment = segments.pop(0)
 
76
            if segment == '.':
 
77
                continue
 
78
            if segment == '..':
 
79
                if len(cwdsegments) > 1:
 
80
                    cwdsegments.pop()
 
81
                continue
 
82
            cwdsegments.append(segment)
 
83
        url = self.base[:self.base.find(':') + 3] + '/'.join(cwdsegments) + '/'
86
84
        result = MemoryTransport(url)
87
85
        result._dirs = self._dirs
88
86
        result._files = self._files
100
98
        else:
101
99
            return temp_t.base[:-1]
102
100
 
103
 
    def append_file(self, relpath, f, mode=None):
104
 
        """See Transport.append_file()."""
 
101
    def append(self, relpath, f, mode=None):
 
102
        """See Transport.append()."""
105
103
        _abspath = self._abspath(relpath)
106
104
        self._check_parent(_abspath)
107
105
        orig_content, orig_mode = self._files.get(_abspath, ("", None))
119
117
    def has(self, relpath):
120
118
        """See Transport.has()."""
121
119
        _abspath = self._abspath(relpath)
122
 
        return (_abspath in self._files) or (_abspath in self._dirs)
 
120
        return _abspath in self._files or _abspath in self._dirs
123
121
 
124
122
    def delete(self, relpath):
125
123
        """See Transport.delete()."""
128
126
            raise NoSuchFile(relpath)
129
127
        del self._files[_abspath]
130
128
 
131
 
    def external_url(self):
132
 
        """See bzrlib.transport.Transport.external_url."""
133
 
        # MemoryTransport's are only accessible in-process
134
 
        # so we raise here
135
 
        raise InProcessTransport(self)
136
 
 
137
129
    def get(self, relpath):
138
130
        """See Transport.get()."""
139
131
        _abspath = self._abspath(relpath)
140
132
        if not _abspath in self._files:
141
 
            if _abspath in self._dirs:
142
 
                return LateReadError(relpath)
143
 
            else:
144
 
                raise NoSuchFile(relpath)
 
133
            raise NoSuchFile(relpath)
145
134
        return StringIO(self._files[_abspath][0])
146
135
 
147
 
    def put_file(self, relpath, f, mode=None):
148
 
        """See Transport.put_file()."""
 
136
    def put(self, relpath, f, mode=None):
 
137
        """See Transport.put()."""
149
138
        _abspath = self._abspath(relpath)
150
139
        self._check_parent(_abspath)
151
 
        bytes = f.read()
152
 
        if type(bytes) is not str:
153
 
            # Although not strictly correct, we raise UnicodeEncodeError to be
154
 
            # compatible with other transports.
155
 
            raise UnicodeEncodeError(
156
 
                'undefined', bytes, 0, 1,
157
 
                'put_file must be given a file of bytes, not unicode.')
158
 
        self._files[_abspath] = (bytes, mode)
 
140
        self._files[_abspath] = (f.read(), mode)
159
141
 
160
142
    def mkdir(self, relpath, mode=None):
161
143
        """See Transport.mkdir()."""
172
154
    def iter_files_recursive(self):
173
155
        for file in self._files:
174
156
            if file.startswith(self._cwd):
175
 
                yield urlutils.escape(file[len(self._cwd):])
 
157
                yield file[len(self._cwd):]
176
158
    
177
159
    def list_dir(self, relpath):
178
160
        """See Transport.list_dir()."""
180
162
        if _abspath != '/' and _abspath not in self._dirs:
181
163
            raise NoSuchFile(relpath)
182
164
        result = []
183
 
 
184
 
        if not _abspath.endswith('/'):
185
 
            _abspath += '/'
186
 
 
187
 
        for path_group in self._files, self._dirs:
188
 
            for path in path_group:
189
 
                if path.startswith(_abspath):
190
 
                    trailing = path[len(_abspath):]
191
 
                    if trailing and '/' not in trailing:
192
 
                        result.append(trailing)
193
 
        return map(urlutils.escape, result)
 
165
        for path in self._files:
 
166
            if (path.startswith(_abspath) and 
 
167
                path[len(_abspath) + 1:].find('/') == -1 and
 
168
                len(path) > len(_abspath)):
 
169
                result.append(path[len(_abspath) + 1:])
 
170
        for path in self._dirs:
 
171
            if (path.startswith(_abspath) and 
 
172
                path[len(_abspath) + 1:].find('/') == -1 and
 
173
                len(path) > len(_abspath) and
 
174
                path[len(_abspath)] == '/'):
 
175
                result.append(path[len(_abspath) + 1:])
 
176
        return result
194
177
 
195
178
    def rename(self, rel_from, rel_to):
196
179
        """Rename a file or directory; fail if the destination exists"""
219
202
        if _abspath in self._files:
220
203
            self._translate_error(IOError(errno.ENOTDIR, relpath), relpath)
221
204
        for path in self._files:
222
 
            if path.startswith(_abspath + '/'):
 
205
            if path.startswith(_abspath):
223
206
                self._translate_error(IOError(errno.ENOTEMPTY, relpath),
224
207
                                      relpath)
225
208
        for path in self._dirs:
226
 
            if path.startswith(_abspath + '/') and path != _abspath:
 
209
            if path.startswith(_abspath) and path != _abspath:
227
210
                self._translate_error(IOError(errno.ENOTEMPTY, relpath), relpath)
228
211
        if not _abspath in self._dirs:
229
212
            raise NoSuchFile(relpath)
253
236
        relpath = urlutils.unescape(relpath)
254
237
        if relpath.find('..') != -1:
255
238
            raise AssertionError('relpath contains ..')
256
 
        if relpath == '':
257
 
            return '/'
258
 
        if relpath[0] == '/':
259
 
            return relpath
260
239
        if relpath == '.':
261
240
            if (self._cwd == '/'):
262
241
                return self._cwd