os.odin 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package os
  2. import "core:mem"
  3. import "core:strconv"
  4. import "core:unicode/utf8"
  5. write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
  6. return write(fd, cast([]byte)str);
  7. }
  8. write_byte :: proc(fd: Handle, b: byte) -> (int, Errno) {
  9. return write(fd, []byte{b});
  10. }
  11. write_rune :: proc(fd: Handle, r: rune) -> (int, Errno) {
  12. if r < utf8.RUNE_SELF {
  13. return write_byte(fd, byte(r));
  14. }
  15. b, n := utf8.encode_rune(r);
  16. return write(fd, b[:n]);
  17. }
  18. write_encoded_rune :: proc(fd: Handle, r: rune) {
  19. write_byte(fd, '\'');
  20. switch r {
  21. case '\a': write_string(fd, "\\a");
  22. case '\b': write_string(fd, "\\b");
  23. case '\e': write_string(fd, "\\e");
  24. case '\f': write_string(fd, "\\f");
  25. case '\n': write_string(fd, "\\n");
  26. case '\r': write_string(fd, "\\r");
  27. case '\t': write_string(fd, "\\t");
  28. case '\v': write_string(fd, "\\v");
  29. case:
  30. if r < 32 {
  31. write_string(fd, "\\x");
  32. b: [2]byte;
  33. s := strconv.append_bits(b[:], u64(r), 16, true, 64, strconv.digits, nil);
  34. switch len(s) {
  35. case 0: write_string(fd, "00");
  36. case 1: write_rune(fd, '0');
  37. case 2: write_string(fd, s);
  38. }
  39. } else {
  40. write_rune(fd, r);
  41. }
  42. }
  43. write_byte(fd, '\'');
  44. }
  45. read_entire_file :: proc(name: string) -> (data: []byte, success: bool) {
  46. fd, err := open(name, O_RDONLY, 0);
  47. if err != 0 {
  48. return nil, false;
  49. }
  50. defer close(fd);
  51. length: i64;
  52. if length, err = file_size(fd); err != 0 {
  53. return nil, false;
  54. }
  55. if length <= 0 {
  56. return nil, true;
  57. }
  58. data = make([]byte, int(length));
  59. if data == nil {
  60. return nil, false;
  61. }
  62. bytes_read, read_err := read(fd, data);
  63. if read_err != 0 {
  64. delete(data);
  65. return nil, false;
  66. }
  67. return data[0:bytes_read], true;
  68. }
  69. write_entire_file :: proc(name: string, data: []byte, truncate := true) -> (success: bool) {
  70. flags: int = O_WRONLY|O_CREATE;
  71. if truncate {
  72. flags |= O_TRUNC;
  73. }
  74. fd, err := open(name, flags, 0);
  75. if err != 0 {
  76. return false;
  77. }
  78. defer close(fd);
  79. _, write_err := write(fd, data);
  80. return write_err == 0;
  81. }
  82. write_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) {
  83. s := transmute([]byte)mem.Raw_Slice{data, len};
  84. return write(fd, s);
  85. }
  86. read_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (int, Errno) {
  87. s := transmute([]byte)mem.Raw_Slice{data, len};
  88. return read(fd, s);
  89. }
  90. heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
  91. size, alignment: int,
  92. old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr {
  93. using mem.Allocator_Mode;
  94. switch mode {
  95. case Alloc:
  96. return heap_alloc(size);
  97. case Free:
  98. heap_free(old_memory);
  99. return nil;
  100. case Free_All:
  101. // NOTE(bill): Does nothing
  102. case Resize:
  103. if old_memory == nil {
  104. return heap_alloc(size);
  105. }
  106. ptr := heap_resize(old_memory, size);
  107. assert(ptr != nil);
  108. return ptr;
  109. }
  110. return nil;
  111. }
  112. heap_allocator :: proc() -> mem.Allocator {
  113. return mem.Allocator{
  114. procedure = heap_allocator_proc,
  115. data = nil,
  116. };
  117. }