writer.inc 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. ; vim:ft=fasm:
  2. ;include 'utils.inc'
  3. ;include 'align.inc'
  4. ;include 'struct.inc'
  5. ;include 'interface.inc'
  6. ;if ~ defined Writer
  7. interface Writer
  8. write buf, size
  9. end interface
  10. struct _Buffer
  11. data dq ?
  12. size dq ?
  13. capacity dq ?
  14. ends
  15. struct BufferedWriter.data
  16. buf _Buffer
  17. writer dq ?
  18. ends
  19. BufferedWriter.buffer_size = (byte * 0x1000 * 0x80)
  20. proc BufferedWriter.write
  21. .self = r15
  22. .self.data = r14
  23. .new_size = r13
  24. .old_size = r12
  25. .buf = rdi
  26. .len = rsi
  27. using_regs .self, .self.data, .new_size, .old_size
  28. mov .self, rax
  29. interface.self_data .self, .self.data
  30. .check_size:
  31. mov .old_size, [.self.data + BufferedWriter.data.buf.size]
  32. lea .new_size, [.old_size + .len]
  33. cmp [.self.data + BufferedWriter.data.buf.capacity], .new_size
  34. jge .capcity_ok
  35. .capcity_exceeded:
  36. mov rax, .self
  37. using_regs .len, .buf
  38. call BufferedWriter.flush ; TODO: check fail
  39. end using_regs
  40. cmp [.self.data + BufferedWriter.data.buf.capacity], .len
  41. jge .check_size
  42. .write_too_big:
  43. using_regs .len, .buf
  44. Writer.write [.self.data + BufferedWriter.data.writer], .buf, .len
  45. end using_regs
  46. jmp .end_reg
  47. .capcity_ok:
  48. mov rdx, .len
  49. .len = rdx
  50. mov rsi, .buf
  51. .buf = rsi
  52. mov rax, [.self.data + BufferedWriter.data.buf.data]
  53. lea rdi, [rax + .old_size]
  54. memcpy rdi, .buf, .len
  55. mov [.self.data + BufferedWriter.data.buf.size], .new_size
  56. .end_reg:
  57. end using_regs
  58. end proc
  59. proc BufferedWriter.flush
  60. .self_data = r15
  61. using_regs .self_data
  62. interface.self_data rax, .self_data
  63. Writer.write [.self_data + BufferedWriter.data.writer], [.self_data + BufferedWriter.data.buf.data], [.self_data + BufferedWriter.data.buf.size]
  64. mov qword [.self_data + BufferedWriter.data.buf.size], 0
  65. end using_regs
  66. end proc
  67. proc FDWriter.write
  68. .buf = rsi
  69. .len = rdx
  70. mov .len, rsi
  71. mov .buf, rdi
  72. interface.self_data rax
  73. write dword [rax], .buf, .len
  74. end proc
  75. ;include 'stdlib.inc'
  76. ;end if