summaryrefslogtreecommitdiff
path: root/user
diff options
context:
space:
mode:
Diffstat (limited to 'user')
-rw-r--r--user/deflate.c68
-rw-r--r--user/include/unistd.h26
-rw-r--r--user/inflate.c41
-rw-r--r--user/lib/fopen.c37
4 files changed, 171 insertions, 1 deletions
diff --git a/user/deflate.c b/user/deflate.c
new file mode 100644
index 0000000..35018d0
--- /dev/null
+++ b/user/deflate.c
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+int main(int argc, char **argv)
+{
+ FILE *in, *out;
+ int length_bytes = 0, length = 0, tracking = EOF, next;
+
+ if (argc != 3) {
+ fprintf(stderr, "usage: deflate in out\n");
+ return 1;
+ }
+
+ in = fopen(argv[1], "rb");
+ if (in == NULL) {
+ fprintf(stderr, "cannot read: %s\n", argv[1]);
+ return 1;
+ }
+
+ out = fopen(argv[2], "wb");
+ if (out == NULL) {
+ fprintf(stderr, "cannot write %s\n", argv[2]);
+ return 1;
+ }
+
+ while (next = getc(in), next != EOF) {
+ int diff;
+
+ if (tracking == EOF) {
+ tracking = next;
+ length = 1;
+ length_bytes = 0;
+ continue;
+ }
+
+ diff = tracking - next;
+ diff = diff < 1 ? -diff : diff;
+ if (diff < 2)
+ next = tracking;
+
+ if (tracking == next) {
+ length++;
+ if (length == 255) {
+ length_bytes++;
+ length = 0;
+ }
+ continue;
+ }
+
+ // write output
+ for (int i = 0; i < length_bytes; i++)
+ putc(255, out);
+ putc(length, out);
+ putc(tracking, out);
+ tracking = next;
+ length = 1;
+ length_bytes = 0;
+ }
+
+ if (length) {
+ for (int i = 0; i < length_bytes; i++)
+ putc(255, out);
+ putc(length, out);
+ putc(tracking, out);
+ }
+
+ return 0;
+}
diff --git a/user/include/unistd.h b/user/include/unistd.h
index f080917..cad3a81 100644
--- a/user/include/unistd.h
+++ b/user/include/unistd.h
@@ -16,6 +16,20 @@
typedef unsigned short pid_t;
+enum {
+ S_SET = 0,
+ S_CUR = 1,
+ S_END = 2,
+};
+
+enum {
+ O_CREATE = 0x01,
+ O_RDONLY = 0x02,
+ O_WRONLY = 0x04,
+ O_APPEND = 0x08,
+ O_RDWR = O_RDONLY | O_WRONLY,
+};
+
/**
* terminates the calling process and does not return.
*
@@ -65,7 +79,7 @@ extern void exec(const char *filename, char **args);
* @param filename - the name of the file to open
* @return the file descriptior of the open file or a negative error code.
*/
-extern int open(const char *filename);
+extern int open(const char *filename, int flags);
/**
* closes a stream with the given file descriptior
@@ -95,6 +109,16 @@ extern int read(int fd, void *buffer, size_t nbytes);
extern int write(int fd, const void *buffer, size_t nbytes);
/**
+ * seek a file
+ *
+ * @param fd - file stream to seek
+ * @param off - offset to seek
+ * @param whence - whence to seek
+ * @return 0 on success, or an error code
+ */
+extern int seek(int fd, long int off, int whence);
+
+/**
* gets the pid of the calling process
*
* @return the pid of this process
diff --git a/user/inflate.c b/user/inflate.c
new file mode 100644
index 0000000..2f7a3d6
--- /dev/null
+++ b/user/inflate.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdbool.h>
+
+int main(int argc, char **argv)
+{
+ FILE *in, *out;
+ int length, value;
+
+ if (argc != 3) {
+ fprintf(stderr, "usage: inflate in out\n");
+ return 1;
+ }
+
+ in = fopen(argv[1], "rb");
+ if (in == NULL) {
+ fprintf(stderr, "cannot read: %s\n", argv[1]);
+ return 1;
+ }
+
+ out = fopen(argv[2], "wb");
+ if (out == NULL) {
+ fprintf(stderr, "cannot write %s\n", argv[2]);
+ return 1;
+ }
+
+ while (1) {
+ length = getc(in);
+ value = getc(in);
+
+ if (length == EOF)
+ break;
+
+ if (value == EOF)
+ return 1;
+
+ for (int i = 0; i < length; i++)
+ putc(value, out);
+ }
+
+ return 0;
+}
diff --git a/user/lib/fopen.c b/user/lib/fopen.c
new file mode 100644
index 0000000..cb2529f
--- /dev/null
+++ b/user/lib/fopen.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <unistd.h>
+
+FILE *fopen(const char *restrict filename, const char *restrict modes)
+{
+ int flags = 0;
+ int fd;
+
+ char c;
+ while (c = *modes, c) {
+ switch (c) {
+ case 'r':
+ flags |= O_RDONLY;
+ break;
+ case 'w':
+ flags |= O_CREATE | O_WRONLY;
+ break;
+ case 'a':
+ flags |= O_APPEND;
+ break;
+ case '+':
+ flags |= O_RDWR;
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ if (flags == 0)
+ return NULL;
+
+ fd = open(filename, flags);
+ if (fd < 0)
+ return NULL;
+
+ return (FILE *)(uintptr_t)fd;
+}