Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-backend / pithos / backends / lib / hashfiler / context_file.py @ c3ec3b3b

History | View | Annotate | Download (5.5 kB)

1 2e662088 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 2715ade4 Sofia Papagiannaki
#
3 a9b3f29d Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 a9b3f29d Antony Chazapis
# without modification, are permitted provided that the following
5 a9b3f29d Antony Chazapis
# conditions are met:
6 2715ade4 Sofia Papagiannaki
#
7 a9b3f29d Antony Chazapis
#   1. Redistributions of source code must retain the above
8 a9b3f29d Antony Chazapis
#      copyright notice, this list of conditions and the following
9 a9b3f29d Antony Chazapis
#      disclaimer.
10 2715ade4 Sofia Papagiannaki
#
11 a9b3f29d Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 a9b3f29d Antony Chazapis
#      copyright notice, this list of conditions and the following
13 a9b3f29d Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 a9b3f29d Antony Chazapis
#      provided with the distribution.
15 2715ade4 Sofia Papagiannaki
#
16 a9b3f29d Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a9b3f29d Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a9b3f29d Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a9b3f29d Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a9b3f29d Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a9b3f29d Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a9b3f29d Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a9b3f29d Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a9b3f29d Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a9b3f29d Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a9b3f29d Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a9b3f29d Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 2715ade4 Sofia Papagiannaki
#
29 a9b3f29d Antony Chazapis
# The views and conclusions contained in the software and
30 a9b3f29d Antony Chazapis
# documentation are those of the authors and should not be
31 a9b3f29d Antony Chazapis
# interpreted as representing official policies, either expressed
32 a9b3f29d Antony Chazapis
# or implied, of GRNET S.A.
33 a9b3f29d Antony Chazapis
34 c3ec3b3b Chrysostomos Nanakos
from os import (
35 c3ec3b3b Chrysostomos Nanakos
    SEEK_CUR,
36 c3ec3b3b Chrysostomos Nanakos
    SEEK_SET,
37 c3ec3b3b Chrysostomos Nanakos
    O_RDONLY,
38 c3ec3b3b Chrysostomos Nanakos
    O_WRONLY,
39 c3ec3b3b Chrysostomos Nanakos
    O_RDWR
40 c3ec3b3b Chrysostomos Nanakos
)
41 a9b3f29d Antony Chazapis
42 a9b3f29d Antony Chazapis
_zeros = ''
43 a9b3f29d Antony Chazapis
44 a9b3f29d Antony Chazapis
45 a9b3f29d Antony Chazapis
def zeros(nr):
46 a9b3f29d Antony Chazapis
    global _zeros
47 a9b3f29d Antony Chazapis
    size = len(_zeros)
48 a9b3f29d Antony Chazapis
    if nr == size:
49 a9b3f29d Antony Chazapis
        return _zeros
50 a9b3f29d Antony Chazapis
51 a9b3f29d Antony Chazapis
    if nr > size:
52 a9b3f29d Antony Chazapis
        _zeros += '\0' * (nr - size)
53 a9b3f29d Antony Chazapis
        return _zeros
54 a9b3f29d Antony Chazapis
55 a9b3f29d Antony Chazapis
    if nr < size:
56 a9b3f29d Antony Chazapis
        _zeros = _zeros[:nr]
57 a9b3f29d Antony Chazapis
        return _zeros
58 a9b3f29d Antony Chazapis
59 a9b3f29d Antony Chazapis
60 a9b3f29d Antony Chazapis
def file_sync_write_chunks(openfile, chunksize, offset, chunks, size=None):
61 a9b3f29d Antony Chazapis
    """Write given chunks to the given buffered file object.
62 a9b3f29d Antony Chazapis
       Writes never span across chunk boundaries.
63 a9b3f29d Antony Chazapis
       If size is given stop after or pad until size bytes have been written.
64 a9b3f29d Antony Chazapis
    """
65 a9b3f29d Antony Chazapis
    fwrite = openfile.write
66 a9b3f29d Antony Chazapis
    seek = openfile.seek
67 a9b3f29d Antony Chazapis
    padding = 0
68 a9b3f29d Antony Chazapis
69 a9b3f29d Antony Chazapis
    try:
70 a9b3f29d Antony Chazapis
        seek(offset * chunksize)
71 29148653 Sofia Papagiannaki
    except IOError:
72 a9b3f29d Antony Chazapis
        seek = None
73 a9b3f29d Antony Chazapis
        for x in xrange(offset):
74 a9b3f29d Antony Chazapis
            fwrite(zeros(chunksize))
75 a9b3f29d Antony Chazapis
76 a9b3f29d Antony Chazapis
    cursize = offset * chunksize
77 a9b3f29d Antony Chazapis
78 a9b3f29d Antony Chazapis
    for chunk in chunks:
79 a9b3f29d Antony Chazapis
        if padding:
80 a9b3f29d Antony Chazapis
            if seek:
81 2715ade4 Sofia Papagiannaki
                seek(padding - 1, SEEK_CUR)
82 a9b3f29d Antony Chazapis
                fwrite("\x00")
83 a9b3f29d Antony Chazapis
            else:
84 a9b3f29d Antony Chazapis
                fwrite(buffer(zeros(chunksize), 0, padding))
85 a9b3f29d Antony Chazapis
        if size is not None and cursize + chunksize >= size:
86 a9b3f29d Antony Chazapis
            chunk = chunk[:chunksize - (cursize - size)]
87 a9b3f29d Antony Chazapis
            fwrite(chunk)
88 a9b3f29d Antony Chazapis
            cursize += len(chunk)
89 a9b3f29d Antony Chazapis
            break
90 a9b3f29d Antony Chazapis
        fwrite(chunk)
91 a9b3f29d Antony Chazapis
        padding = chunksize - len(chunk)
92 a9b3f29d Antony Chazapis
93 a9b3f29d Antony Chazapis
    padding = size - cursize if size is not None else 0
94 a9b3f29d Antony Chazapis
    if padding <= 0:
95 a9b3f29d Antony Chazapis
        return
96 a9b3f29d Antony Chazapis
97 a9b3f29d Antony Chazapis
    q, r = divmod(padding, chunksize)
98 a9b3f29d Antony Chazapis
    for x in xrange(q):
99 a9b3f29d Antony Chazapis
        fwrite(zeros(chunksize))
100 a9b3f29d Antony Chazapis
    fwrite(buffer(zeros(chunksize), 0, r))
101 a9b3f29d Antony Chazapis
102 a9b3f29d Antony Chazapis
103 a9b3f29d Antony Chazapis
def file_sync_read_chunks(openfile, chunksize, nr, offset=0):
104 a9b3f29d Antony Chazapis
    """Read and yield groups of chunks from a buffered file object at offset.
105 a9b3f29d Antony Chazapis
       Reads never span accros chunksize boundaries.
106 a9b3f29d Antony Chazapis
    """
107 a9b3f29d Antony Chazapis
    fread = openfile.read
108 a9b3f29d Antony Chazapis
    remains = offset * chunksize
109 a9b3f29d Antony Chazapis
    seek = openfile.seek
110 a9b3f29d Antony Chazapis
    try:
111 a9b3f29d Antony Chazapis
        seek(remains)
112 29148653 Sofia Papagiannaki
    except IOError:
113 a9b3f29d Antony Chazapis
        seek = None
114 a9b3f29d Antony Chazapis
        while 1:
115 a9b3f29d Antony Chazapis
            s = fread(remains)
116 a9b3f29d Antony Chazapis
            remains -= len(s)
117 a9b3f29d Antony Chazapis
            if remains <= 0:
118 a9b3f29d Antony Chazapis
                break
119 a9b3f29d Antony Chazapis
120 a9b3f29d Antony Chazapis
    while nr:
121 a9b3f29d Antony Chazapis
        remains = chunksize
122 a9b3f29d Antony Chazapis
        chunk = ''
123 a9b3f29d Antony Chazapis
        while 1:
124 a9b3f29d Antony Chazapis
            s = fread(remains)
125 a9b3f29d Antony Chazapis
            if not s:
126 a9b3f29d Antony Chazapis
                if chunk:
127 a9b3f29d Antony Chazapis
                    yield chunk
128 a9b3f29d Antony Chazapis
                return
129 a9b3f29d Antony Chazapis
            chunk += s
130 a9b3f29d Antony Chazapis
            remains -= len(s)
131 a9b3f29d Antony Chazapis
            if remains <= 0:
132 a9b3f29d Antony Chazapis
                break
133 a9b3f29d Antony Chazapis
        yield chunk
134 a9b3f29d Antony Chazapis
        nr -= 1
135 a9b3f29d Antony Chazapis
136 a9b3f29d Antony Chazapis
137 a9b3f29d Antony Chazapis
class ContextFile(object):
138 c3ec3b3b Chrysostomos Nanakos
    __slots__ = ("name", "fdesc", "oflag")
139 a9b3f29d Antony Chazapis
140 c3ec3b3b Chrysostomos Nanakos
    def __init__(self, name, oflag):
141 a9b3f29d Antony Chazapis
        self.name = name
142 a9b3f29d Antony Chazapis
        self.fdesc = None
143 c3ec3b3b Chrysostomos Nanakos
        self.oflag = oflag
144 a9b3f29d Antony Chazapis
        #self.dirty = 0
145 a9b3f29d Antony Chazapis
146 a9b3f29d Antony Chazapis
    def __enter__(self):
147 a9b3f29d Antony Chazapis
        name = self.name
148 c3ec3b3b Chrysostomos Nanakos
        if self.oflag == O_RDONLY:
149 c3ec3b3b Chrysostomos Nanakos
            fdesc = open(name, 'rb')
150 c3ec3b3b Chrysostomos Nanakos
        elif self.oflag == O_WRONLY:
151 c3ec3b3b Chrysostomos Nanakos
            fdesc = open(name, 'wb')
152 c3ec3b3b Chrysostomos Nanakos
        elif self.oflag == O_RDWR:
153 c3ec3b3b Chrysostomos Nanakos
            fdesc = open(name, 'wb+')
154 c3ec3b3b Chrysostomos Nanakos
        else:
155 c3ec3b3b Chrysostomos Nanakos
            raise Exception("Wrong file acccess mode.")
156 a9b3f29d Antony Chazapis
157 a9b3f29d Antony Chazapis
        self.fdesc = fdesc
158 a9b3f29d Antony Chazapis
        return self
159 a9b3f29d Antony Chazapis
160 a9b3f29d Antony Chazapis
    def __exit__(self, exc, arg, trace):
161 a9b3f29d Antony Chazapis
        fdesc = self.fdesc
162 a9b3f29d Antony Chazapis
        if fdesc is not None:
163 a9b3f29d Antony Chazapis
            #if self.dirty:
164 a9b3f29d Antony Chazapis
            #    fsync(fdesc.fileno())
165 a9b3f29d Antony Chazapis
            fdesc.close()
166 2715ade4 Sofia Papagiannaki
        return False  # propagate exceptions
167 a9b3f29d Antony Chazapis
168 a9b3f29d Antony Chazapis
    def seek(self, offset, whence=SEEK_SET):
169 a9b3f29d Antony Chazapis
        return self.fdesc.seek(offset, whence)
170 a9b3f29d Antony Chazapis
171 a9b3f29d Antony Chazapis
    def tell(self):
172 a9b3f29d Antony Chazapis
        return self.fdesc.tell()
173 a9b3f29d Antony Chazapis
174 a9b3f29d Antony Chazapis
    def truncate(self, size):
175 a9b3f29d Antony Chazapis
        self.fdesc.truncate(size)
176 a9b3f29d Antony Chazapis
177 a9b3f29d Antony Chazapis
    def sync_write(self, data):
178 a9b3f29d Antony Chazapis
        #self.dirty = 1
179 a9b3f29d Antony Chazapis
        self.fdesc.write(data)
180 a9b3f29d Antony Chazapis
181 a9b3f29d Antony Chazapis
    def sync_write_chunks(self, chunksize, offset, chunks, size=None):
182 a9b3f29d Antony Chazapis
        #self.dirty = 1
183 29148653 Sofia Papagiannaki
        return file_sync_write_chunks(self.fdesc, chunksize, offset, chunks,
184 29148653 Sofia Papagiannaki
                                      size)
185 a9b3f29d Antony Chazapis
186 a9b3f29d Antony Chazapis
    def sync_read(self, size):
187 a9b3f29d Antony Chazapis
        read = self.fdesc.read
188 a9b3f29d Antony Chazapis
        data = ''
189 a9b3f29d Antony Chazapis
        while 1:
190 a9b3f29d Antony Chazapis
            s = read(size)
191 a9b3f29d Antony Chazapis
            if not s:
192 a9b3f29d Antony Chazapis
                break
193 a9b3f29d Antony Chazapis
            data += s
194 a9b3f29d Antony Chazapis
        return data
195 a9b3f29d Antony Chazapis
196 a9b3f29d Antony Chazapis
    def sync_read_chunks(self, chunksize, nr, offset=0):
197 a9b3f29d Antony Chazapis
        return file_sync_read_chunks(self.fdesc, chunksize, nr, offset)