Commit f9c8da8c authored by Xavier Thompson's avatar Xavier Thompson

Improve scan.pyx

parent 6f79ca87
...@@ -21,6 +21,7 @@ cdef Str sep = Str("/") ...@@ -21,6 +21,7 @@ cdef Str sep = Str("/")
cdef char * file_fmt = """\ cdef char * file_fmt = """\
[{}] [{}]
type = file
sha256 = {} sha256 = {}
sha512 = {} sha512 = {}
{} {}
...@@ -29,12 +30,14 @@ sha512 = {} ...@@ -29,12 +30,14 @@ sha512 = {}
cdef char * dir_fmt = """\ cdef char * dir_fmt = """\
[{}] [{}]
type = dir
{} {}
""" """
cdef char * symlink_fmt = """\ cdef char * symlink_fmt = """\
[{}] [{}]
type = symlink
target = {} target = {}
{} {}
...@@ -66,9 +69,9 @@ cdef cypclass Node activable: ...@@ -66,9 +69,9 @@ cdef cypclass Node activable:
void build_node(self): pass void build_node(self): pass
void format_node(self): pass void write_node(self, FILE * stream): pass
Str format_stat(self): Str to_toml(self):
return format(stat_fmt, return format(stat_fmt,
self.stat.st_dev, self.stat.st_dev,
self.stat.st_ino, self.stat.st_ino,
...@@ -88,15 +91,13 @@ cdef cypclass Node activable: ...@@ -88,15 +91,13 @@ cdef cypclass Node activable:
self.stat.st_ctim.tv_nsec, self.stat.st_ctim.tv_nsec,
) )
void write_node(self, FILE * stream): pass
@staticmethod @staticmethod
iso Node create(iso Str path): iso Node node(iso Str path):
cdef Node node cdef Node node
p = <Str> consume path p = <Str> consume path
s = os.stat(p) s = os.stat(p)
if s is NULL: if s is NULL:
node = NULL return NULL
elif s.is_symlink(): elif s.is_symlink():
node = SymlinkNode(p, s) node = SymlinkNode(p, s)
elif s.is_dir(): elif s.is_dir():
...@@ -104,7 +105,7 @@ cdef cypclass Node activable: ...@@ -104,7 +105,7 @@ cdef cypclass Node activable:
elif s.is_regular(): elif s.is_regular():
node = FileNode(p, s) node = FileNode(p, s)
else: else:
node = NULL return NULL
del p, s del p, s
return consume node return consume node
...@@ -125,23 +126,21 @@ cdef cypclass DirNode(Node): ...@@ -125,23 +126,21 @@ cdef cypclass DirNode(Node):
continue continue
path = self.path path = self.path
if Str(path[-1]) != sep: if Str(path[-1]) != sep:
path = path + sep path = path + sep
path = path + name path = path + name
child = Node.create(consume path) child = Node.node(consume path)
if child is not NULL: if child is not NULL:
self.children.append(activate(consume child)) self.children.append(activate(consume child))
self.format_node()
for active_child in self.children:
active_child.build_node(NULL)
void format_node(self):
self.text = format(dir_fmt, self.text = format(dir_fmt,
self.path, self.path,
self.format_stat(), self.to_toml(),
) )
for active_child in self.children:
active_child.build_node(NULL)
pass
void write_node(self, FILE * stream): void write_node(self, FILE * stream):
os.write(self.text, stream) os.write(self.text, stream)
while self.children.__len__() > 0: while self.children.__len__() > 0:
...@@ -150,9 +149,7 @@ cdef cypclass DirNode(Node): ...@@ -150,9 +149,7 @@ cdef cypclass DirNode(Node):
child.write_node(stream) child.write_node(stream)
cdef enum: cdef enum: CHUNK = 64 * 1024
CHUNK = 64 * 1024
cdef cypclass FileNode(Node): cdef cypclass FileNode(Node):
Str sha256 Str sha256
...@@ -162,89 +159,71 @@ cdef cypclass FileNode(Node): ...@@ -162,89 +159,71 @@ cdef cypclass FileNode(Node):
Node.__init__(self, path, stat) Node.__init__(self, path, stat)
void build_node(self): void build_node(self):
cdef bint sha256_ok cdef bint sha256_ok = False
cdef bint sha512_ok cdef bint sha512_ok = False
cdef bint error = False
cdef FILE * file = os.open(self.path, 'rb') file = os.open(self.path, 'rb')
if file is NULL: if file is not NULL:
self.format_node()
return
sha256 = hashlib.Hash(hashlib.sha256()) sha256 = hashlib.Hash(hashlib.sha256())
sha512 = hashlib.Hash(hashlib.sha512()) sha512 = hashlib.Hash(hashlib.sha512())
sha256_ok = sha256 is not NULL sha256_ok = sha256 is not NULL
sha512_ok = sha512 is not NULL sha512_ok = sha512 is not NULL
while (sha256_ok or sha512_ok): while (sha256_ok or sha512_ok):
s = os.read(file, CHUNK) s = os.read(file, CHUNK)
if s is NULL: if s is NULL:
error = True sha256_ok = sha512_ok = False
break break
if sha256_ok: if sha256_ok:
sha256_ok = sha256.update(s) == 0 sha256_ok = sha256.update(s) == 0
if sha512_ok: if sha512_ok:
sha512_ok = sha512.update(s) == 0 sha512_ok = sha512.update(s) == 0
if s.__len__() != CHUNK: if s.__len__() != CHUNK:
break break
os.close(file) os.close(file)
if not error:
self.sha256 = sha256.hexdigest() if sha256_ok else NULL self.sha256 = sha256.hexdigest() if sha256_ok else NULL
self.sha512 = sha512.hexdigest() if sha512_ok else NULL self.sha512 = sha512.hexdigest() if sha512_ok else NULL
self.format_node()
void format_node(self):
sha256 = self.sha256 if self.sha256 else Str("<error>")
sha512 = self.sha512 if self.sha512 else Str("<error>")
self.text = format(file_fmt, self.text = format(file_fmt,
self.path, self.path,
sha256, self.sha256 if self.sha256 else Str("<error>"),
sha512, self.sha512 if self.sha512 else Str("<error>"),
self.format_stat(), self.to_toml(),
) )
void write_node(self, FILE * stream):
os.write(self.text, stream)
cdef cypclass SymlinkNode(Node): cdef cypclass SymlinkNode(Node):
Str target Str target
void build_node(self): void build_node(self):
self.target = os.readlink(self.path, self.stat.st_size) target = os.readlink(self.path, self.stat.st_size)
self.format_node() if target is NULL:
target = Str("<error>")
void format_node(self): self.target = target
target = self.target if self.target is not NULL else Str("<error>")
self.text = format(symlink_fmt, self.text = format(symlink_fmt,
self.path, self.path,
target, target,
self.format_stat(), self.to_toml(),
) )
void write_node(self, FILE * stream):
os.write(self.text, stream)
cdef int scan(iso Str path) nogil:
cdef int scan(iso Str root) nogil: root = Node.node(consume path)
node = Node.create(consume root) if root is NULL:
if node is NULL:
return -1 return -1
active_node = activate(consume node) root.build_node()
active_node.build_node(NULL)
scheduler.join() scheduler.join()
node = consume active_node root.write_node(os.stdout)
node.write_node(os.stdout)
return 0 return 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment