diff options
Diffstat (limited to 'stdlib')
| -rw-r--r-- | stdlib/bytes.c | 38 | ||||
| -rw-r--r-- | stdlib/bytes.h | 29 | ||||
| -rw-r--r-- | stdlib/integers.c | 8 | ||||
| -rw-r--r-- | stdlib/paths.c | 60 | ||||
| -rw-r--r-- | stdlib/paths.h | 4 | ||||
| -rw-r--r-- | stdlib/tomo.h | 1 |
6 files changed, 118 insertions, 22 deletions
diff --git a/stdlib/bytes.c b/stdlib/bytes.c new file mode 100644 index 00000000..5b471bfe --- /dev/null +++ b/stdlib/bytes.c @@ -0,0 +1,38 @@ +// The logic for unsigned bytes +#include <stdbool.h> +#include <stdint.h> + +#include "bytes.h" +#include "stdlib.h" +#include "text.h" +#include "util.h" + +public const Byte_t Byte$min = 0; +public const Byte_t Byte$max = UINT8_MAX; + +PUREFUNC public Text_t Byte$as_text(const Byte_t *b, bool colorize, const TypeInfo *type) +{ + (void)type; + if (!b) return Text("Byte"); + return Text$format(colorize ? "\x1b[35m%u[B]\x1b[m" : "%u[B]", *b); +} + +public Byte_t Byte$random(Byte_t min, Byte_t max) +{ + if (min > max) + fail("Random minimum value (%u) is larger than the maximum value (%u)", min, max); + if (min == max) + return min; + + uint32_t r = arc4random_uniform((uint32_t)max - (uint32_t)min + 1u); + return (Byte_t)(min + r); +} + +public const TypeInfo Byte$info = { + .size=sizeof(Byte_t), + .align=__alignof__(Byte_t), + .tag=CustomInfo, + .CustomInfo={.as_text=(void*)Byte$as_text}, +}; + +// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/bytes.h b/stdlib/bytes.h new file mode 100644 index 00000000..d74ab80c --- /dev/null +++ b/stdlib/bytes.h @@ -0,0 +1,29 @@ +#pragma once + +// An unsigned byte datatype + +#include <stdbool.h> +#include <stdint.h> + +#include "types.h" +#include "util.h" + +#define Byte_t uint8_t +#define Byte(b) ((Byte_t)(b)) + +PUREFUNC Text_t Byte$as_text(const Byte_t *b, bool colorize, const TypeInfo *type); +Byte_t Byte$random(Byte_t min, Byte_t max); + +extern const Byte_t Byte$min; +extern const Byte_t Byte$max; + +extern const TypeInfo Byte$info; + +typedef struct { + Byte_t value; + bool is_null:1; +} OptionalByte_t; + +#define NULL_BYTE ((OptionalByte_t){.is_null=true}) + +// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/integers.c b/stdlib/integers.c index ef588984..6caac31e 100644 --- a/stdlib/integers.c +++ b/stdlib/integers.c @@ -481,10 +481,10 @@ public const TypeInfo Int$info = { .CustomInfo={.compare=(void*)KindOfInt##$compare, .as_text=(void*)KindOfInt##$as_text}, \ }; -DEFINE_INT_TYPE(int64_t, Int64, "ld_i64", INT64_MIN, INT64_MAX) -DEFINE_INT_TYPE(int32_t, Int32, "d_i32", INT32_MIN, INT32_MAX) -DEFINE_INT_TYPE(int16_t, Int16, "d_i16", INT16_MIN, INT16_MAX) -DEFINE_INT_TYPE(int8_t, Int8, "d_i8", INT8_MIN, INT8_MAX) +DEFINE_INT_TYPE(int64_t, Int64, "ld[64]", INT64_MIN, INT64_MAX) +DEFINE_INT_TYPE(int32_t, Int32, "d[32]", INT32_MIN, INT32_MAX) +DEFINE_INT_TYPE(int16_t, Int16, "d[16]", INT16_MIN, INT16_MAX) +DEFINE_INT_TYPE(int8_t, Int8, "d[8]", INT8_MIN, INT8_MAX) #undef DEFINE_INT_TYPE // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/stdlib/paths.c b/stdlib/paths.c index 231a7c23..bebb9389 100644 --- a/stdlib/paths.c +++ b/stdlib/paths.c @@ -207,7 +207,7 @@ public bool Path$is_symlink(Path_t path) return (sb.st_mode & S_IFMT) == S_IFLNK; } -static void _write(Path_t path, Text_t text, int mode, int permissions) +static void _write(Path_t path, Array_t bytes, int mode, int permissions) { path = Path$_expand_home(path); const char *path_str = Text$as_c_string(path); @@ -215,24 +215,36 @@ static void _write(Path_t path, Text_t text, int mode, int permissions) if (fd == -1) fail("Could not write to file: %s\n%s", path_str, strerror(errno)); - const char *str = Text$as_c_string(text); - size_t len = strlen(str); - ssize_t written = write(fd, str, len); - if (written != (ssize_t)len) + if (bytes.stride != 1) + Array$compact(&bytes, 1); + ssize_t written = write(fd, bytes.data, (size_t)bytes.length); + if (written != (ssize_t)bytes.length) fail("Could not write to file: %s\n%s", path_str, strerror(errno)); } public void Path$write(Path_t path, Text_t text, int permissions) { - _write(path, text, O_WRONLY | O_CREAT, permissions); + Array_t bytes = Text$utf8_bytes(text); + _write(path, bytes, O_WRONLY | O_CREAT, permissions); +} + +public void Path$write_bytes(Path_t path, Array_t bytes, int permissions) +{ + _write(path, bytes, O_WRONLY | O_CREAT, permissions); } public void Path$append(Path_t path, Text_t text, int permissions) { - _write(path, text, O_WRONLY | O_APPEND | O_CREAT, permissions); + Array_t bytes = Text$utf8_bytes(text); + _write(path, bytes, O_WRONLY | O_APPEND | O_CREAT, permissions); } -public Text_t Path$read(Path_t path) +public void Path$append_bytes(Path_t path, Array_t bytes, int permissions) +{ + _write(path, bytes, O_WRONLY | O_APPEND | O_CREAT, permissions); +} + +public Array_t Path$read_bytes(Path_t path) { path = Path$_expand_home(path); int fd = open(Text$as_c_string(path), O_RDONLY); @@ -245,11 +257,11 @@ public Text_t Path$read(Path_t path) if ((sb.st_mode & S_IFMT) == S_IFREG) { // Use memory mapping if it's a real file: const char *mem = mmap(NULL, (size_t)sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - char *gc_mem = GC_MALLOC_ATOMIC((size_t)sb.st_size+1); - memcpy(gc_mem, mem, (size_t)sb.st_size); - gc_mem[sb.st_size] = '\0'; + char *content = GC_MALLOC_ATOMIC((size_t)sb.st_size+1); + memcpy(content, mem, (size_t)sb.st_size); + content[sb.st_size] = '\0'; close(fd); - return Text$from_strn(gc_mem, (size_t)sb.st_size); + return (Array_t){.data=content, .atomic=1, .stride=1, .length=(int64_t)sb.st_size}; } else { size_t capacity = 256, len = 0; char *content = GC_MALLOC_ATOMIC(capacity); @@ -279,10 +291,16 @@ public Text_t Path$read(Path_t path) if (u8_check((uint8_t*)content, len) != NULL) fail("File does not contain valid UTF8 data!"); - return Text$from_strn(content, len); + return (Array_t){.data=content, .atomic=1, .stride=1, .length=len}; } } +public Text_t Path$read(Path_t path) +{ + Array_t bytes = Path$read_bytes(path); + return Text$from_bytes(bytes); +} + public void Path$remove(Path_t path, bool ignore_missing) { path = Path$_expand_home(path); @@ -375,7 +393,7 @@ public Path_t Path$unique_directory(Path_t path) return Text$format("%s/", created); } -public Text_t Path$write_unique(Path_t path, Text_t text) +public Text_t Path$write_unique_bytes(Path_t path, Array_t bytes) { path = Path$_expand_home(path); const char *path_str = Text$as_c_string(path); @@ -392,14 +410,20 @@ public Text_t Path$write_unique(Path_t path, Text_t text) if (fd == -1) fail("Could not write to unique file: %s\n%s", buf, strerror(errno)); - const char *str = Text$as_c_string(text); - size_t write_len = strlen(str); - ssize_t written = write(fd, str, write_len); - if (written != (ssize_t)write_len) + if (bytes.stride != 1) + Array$compact(&bytes, 1); + + ssize_t written = write(fd, bytes.data, (size_t)bytes.length); + if (written != (ssize_t)bytes.length) fail("Could not write to file: %s\n%s", buf, strerror(errno)); return Text$format("%s", buf); } +public Text_t Path$write_unique(Path_t path, Text_t text) +{ + return Path$write_unique_bytes(path, Text$utf8_bytes(text)); +} + public Path_t Path$parent(Path_t path) { return Path$cleanup(Text$concat(path, Path("/../"))); diff --git a/stdlib/paths.h b/stdlib/paths.h index e0d85258..d06d4fdc 100644 --- a/stdlib/paths.h +++ b/stdlib/paths.h @@ -26,8 +26,11 @@ bool Path$is_pipe(Path_t path, bool follow_symlinks); bool Path$is_socket(Path_t path, bool follow_symlinks); bool Path$is_symlink(Path_t path); void Path$write(Path_t path, Text_t text, int permissions); +void Path$write_bytes(Path_t path, Array_t bytes, int permissions); void Path$append(Path_t path, Text_t text, int permissions); +void Path$append_bytes(Path_t path, Array_t bytes, int permissions); Text_t Path$read(Path_t path); +Array_t Path$read_bytes(Path_t path); void Path$remove(Path_t path, bool ignore_missing); void Path$create_directory(Path_t path, int permissions); Array_t Path$children(Path_t path, bool include_hidden); @@ -35,6 +38,7 @@ Array_t Path$files(Path_t path, bool include_hidden); Array_t Path$subdirectories(Path_t path, bool include_hidden); Path_t Path$unique_directory(Path_t path); Text_t Path$write_unique(Path_t path, Text_t text); +Text_t Path$write_unique_bytes(Path_t path, Array_t bytes); Path_t Path$parent(Path_t path); Text_t Path$base_name(Path_t path); Text_t Path$extension(Path_t path, bool full); diff --git a/stdlib/tomo.h b/stdlib/tomo.h index 7db0f490..d1e61a5d 100644 --- a/stdlib/tomo.h +++ b/stdlib/tomo.h @@ -11,6 +11,7 @@ #include "arrays.h" #include "bools.h" +#include "bytes.h" #include "c_strings.h" #include "channels.h" #include "datatypes.h" |
