summaryrefslogblamecommitdiff
path: root/src/user/lib/fwik/io/Node.cpp
blob: daccc18adf98bd9a44ead82b62815e0336c2a2db (plain) (tree)
1
2
3
4
5
6
7
8
9







                                      
                                            













                                               




















































































                                                                             
#include <IO/Node.h>

Node::Node(FILE f) {
	fd = f;
	int i = libc::statf(f, &info);
	valid = (i == 0);
}

Node::Node(const char* filename, int mode) {
	fd = libc::open(filename, mode);
	if (fd < 0) {
		valid = false;
	} else {
		int i = libc::statf(fd, &info);
		valid = (i == 0);
		if (!valid) libc::close(fd);
	}
}

void Node::close() {
	if (valid) libc::close(fd);
	valid = false;
}

////////

static void simplify_path(char* p) {
	char *it = p;
	char *member = it;
	while (*it != 0) {
		if (*it == '/') {
			if (it == member && it != p) {
				// two consecutive slashes
				char *i = member;
				while (1) {
					i[0] = i[1];
					if (i[0] == 0) break;
					i++;
				}
			} else {
				*it = 0;
				if (libc::strcmp(member, ".") == 0) {
					char *i = member;
					while (1) {
						i[0] = i[2];
						if (i[0] == 0) break;
						i++;
					}
				} else if (libc::strcmp(member, "..") == 0) {
					*it = '/';
					char* start = member - 2;
					char* next = member + 3;
					while (start > p && *start != '/') {
						start--;
					}
					start++;
					it = member = start;
					while (1) {
						*start = *next;
						if (*start == 0) break;
						start++;
						next++;
					}
				} else {
					*it = '/';
					it++;
					member = it;
				}
			}
		} else {
			it++;
		}
	}
}

String path_cat(const String &a, const String &b, bool trailing_slash) {
	int len, la = a.size(), lb = b.size();
	if (b[0] == '/') {
		len = lb + 2;
	} else {
		len = la + lb + 3;
	}
	char buf[len];
	if (b[0] == '/') {
		libc::memcpy(buf, b.c_str(), lb);
		if (buf[lb-1] != '/') {
			buf[lb++] = '/';
		}
		buf[lb] = 0;
	} else {
		libc::memcpy(buf, a.c_str(), la);
		if (buf[la-1] != '/') {
			buf[la++] = '/';
		}
		libc::memcpy(buf + la, b.c_str(), lb);
		if (buf[la + lb - 1] != '/') {
			buf[la + lb] = '/';
			lb++;
		}
		buf[la + lb] = 0;
	}
	simplify_path(buf);
	if (!trailing_slash) {
		int l = libc::strlen(buf);
		if (buf[l-1] == '/') buf[l-1] = 0;
	}
	return String(buf);
}