summaryrefslogtreecommitdiffstats
path: root/src/csv.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/csv.S')
-rw-r--r--src/csv.S297
1 files changed, 297 insertions, 0 deletions
diff --git a/src/csv.S b/src/csv.S
new file mode 100644
index 0000000..9c16a8e
--- /dev/null
+++ b/src/csv.S
@@ -0,0 +1,297 @@
+#include "abi.inc"
+#include "defs.inc"
+
+#define CBUF -72
+
+#define CA_ROWS -72
+#define CA_STATE -80
+#define CA_NF -88
+#define CA_FIELDS -344
+#define CA_MAP -472
+
+ .text
+
+FUNC cepis__csv_row
+ PROLOGUE 56
+ mov %rdi, %rbx
+ mov %rsi, %r14
+ mov %rdx, %r15
+ movl $0, (%r15)
+ mov (%rbx), %r12
+ cmpb $0, (%r12)
+ je .Lrow_eof
+ xor %r13d, %r13d
+.Lfield:
+ cmpb $'"', (%r12)
+ je .Lquoted
+ mov %r12, %rax
+.Lbare_scan:
+ movzbl (%rax), %ecx
+ test %cl, %cl
+ jz .Lbare_end
+ cmp $',', %cl
+ je .Lbare_end
+ cmp $10, %cl
+ je .Lbare_end
+ cmp $13, %cl
+ je .Lbare_end
+ inc %rax
+ jmp .Lbare_scan
+.Lbare_end:
+ mov %rax, LOCAL0(%rbp)
+ mov %rax, %rsi
+ sub %r12, %rsi
+ mov %r12, %rdi
+ call cepis__strndup
+ test %rax, %rax
+ jz .Lrow_err
+ mov LOCAL0(%rbp), %r12
+ jmp .Lstore
+.Lquoted:
+ movq $0, CBUF(%rbp)
+ movq $0, CBUF+8(%rbp)
+ movq $0, CBUF+16(%rbp)
+ inc %r12
+.Lq_loop:
+ movzbl (%r12), %eax
+ test %al, %al
+ jz .Lq_done
+ cmp $'"', %al
+ je .Lq_quote
+ lea CBUF(%rbp), %rdi
+ movzbl (%r12), %esi
+ call cepis__buf_appendc
+ test %eax, %eax
+ jnz .Lq_err
+ inc %r12
+ jmp .Lq_loop
+.Lq_quote:
+ cmpb $'"', 1(%r12)
+ jne .Lq_close
+ lea CBUF(%rbp), %rdi
+ mov $'"', %esi
+ call cepis__buf_appendc
+ test %eax, %eax
+ jnz .Lq_err
+ add $2, %r12
+ jmp .Lq_loop
+.Lq_close:
+ inc %r12
+.Lq_skip:
+ movzbl (%r12), %eax
+ test %al, %al
+ jz .Lq_done
+ cmp $',', %al
+ je .Lq_done
+ cmp $10, %al
+ je .Lq_done
+ cmp $13, %al
+ je .Lq_done
+ inc %r12
+ jmp .Lq_skip
+.Lq_done:
+ cmpq $0, CBUF(%rbp)
+ jne .Lq_take
+ call cepis__empty
+ test %rax, %rax
+ jz .Lrow_err
+ jmp .Lstore
+.Lq_take:
+ lea CBUF(%rbp), %rdi
+ call cepis__buf_take
+.Lstore:
+ cmp $32, %r13
+ jae .Ldrop
+ mov %rax, (%r14, %r13, 8)
+ inc %r13
+ jmp .Lsep
+.Ldrop:
+ mov %rax, %rdi
+ call free@PLT
+.Lsep:
+ movzbl (%r12), %eax
+ cmp $',', %al
+ jne .Lrow_end
+ inc %r12
+ jmp .Lfield
+.Lrow_end:
+ cmpb $13, (%r12)
+ jne .Lrow_nl
+ inc %r12
+.Lrow_nl:
+ cmpb $10, (%r12)
+ jne .Lrow_fin
+ inc %r12
+.Lrow_fin:
+ mov %r12, (%rbx)
+ mov %r13d, (%r15)
+ mov $1, %eax
+ EPILOGUE
+ ret
+.Lrow_eof:
+ xor %eax, %eax
+ EPILOGUE
+ ret
+.Lq_err:
+ lea CBUF(%rbp), %rdi
+ call cepis__buf_free
+.Lrow_err:
+ xor %r12d, %r12d
+.Lrow_err_loop:
+ cmp %r13, %r12
+ jae .Lrow_err_out
+ mov (%r14, %r12, 8), %rdi
+ call free@PLT
+ inc %r12
+ jmp .Lrow_err_loop
+.Lrow_err_out:
+ movl $0, (%r15)
+ mov $-1, %eax
+ EPILOGUE
+ ret
+ENDFUNC cepis__csv_row
+
+FUNC cepis__csv_addresses
+ PROLOGUE 440
+ mov %rsi, %r14
+ mov %rdx, %r15
+ movq $0, (%r14)
+ movq $0, (%r15)
+ movq $0, CA_ROWS(%rbp)
+ movq $0, CA_ROWS+8(%rbp)
+ movq $0, CA_ROWS+16(%rbp)
+ cmpb $0xEF, (%rdi)
+ jne .Lca_nobom
+ cmpb $0xBB, 1(%rdi)
+ jne .Lca_nobom
+ cmpb $0xBF, 2(%rdi)
+ jne .Lca_nobom
+ add $3, %rdi
+.Lca_nobom:
+ mov %rdi, CA_STATE(%rbp)
+ lea CA_STATE(%rbp), %rdi
+ lea CA_FIELDS(%rbp), %rsi
+ lea CA_NF(%rbp), %rdx
+ call cepis__csv_row
+ cmp $1, %eax
+ je .Lca_header
+ cmp $0, %eax
+ je .Lca_invalid
+ jmp .Lca_nomem
+.Lca_header:
+ xor %r12d, %r12d
+.Lca_hdr_loop:
+ movslq CA_NF(%rbp), %rax
+ cmp %rax, %r12
+ jae .Lca_rows
+ mov CA_FIELDS(%rbp, %r12, 8), %rdi
+ call cepis__addr_field_offset
+ lea CA_MAP(%rbp), %rcx
+ mov %eax, (%rcx, %r12, 4)
+ mov CA_FIELDS(%rbp, %r12, 8), %rdi
+ call free@PLT
+ inc %r12
+ jmp .Lca_hdr_loop
+.Lca_rows:
+ lea CA_STATE(%rbp), %rdi
+ lea CA_FIELDS(%rbp), %rsi
+ lea CA_NF(%rbp), %rdx
+ call cepis__csv_row
+ cmp $1, %eax
+ je .Lca_row
+ cmp $0, %eax
+ je .Lca_done
+ jmp .Lca_nomem
+.Lca_row:
+ cmpl $1, CA_NF(%rbp)
+ jne .Lca_build
+ mov CA_FIELDS(%rbp), %rdi
+ cmpb $0, (%rdi)
+ jne .Lca_build
+ call free@PLT
+ jmp .Lca_rows
+.Lca_build:
+ call cepis__address_new
+ test %rax, %rax
+ jz .Lca_nomem_fields
+ mov %rax, %rbx
+ xor %r12d, %r12d
+.Lca_assign:
+ movslq CA_NF(%rbp), %rax
+ cmp %rax, %r12
+ jae .Lca_check
+ lea CA_MAP(%rbp), %rcx
+ movslq (%rcx, %r12, 4), %r13
+ cmp $0, %r13
+ jl .Lca_assign_drop
+ mov %rbx, %rdi
+ mov %r13, %rsi
+ mov CA_FIELDS(%rbp, %r12, 8), %rdx
+ call cepis__addr_set
+ jmp .Lca_assign_next
+.Lca_assign_drop:
+ mov CA_FIELDS(%rbp, %r12, 8), %rdi
+ call free@PLT
+.Lca_assign_next:
+ inc %r12
+ jmp .Lca_assign
+.Lca_check:
+ mov A_LOCALIDADE(%rbx), %rdi
+ cmpb $0, (%rdi)
+ jne .Lca_push
+ mov %rbx, %rdi
+ call cepis_address_free
+ xor %ebx, %ebx
+.Lca_push:
+ mov %rbx, LOCAL0(%rbp)
+ lea CA_ROWS(%rbp), %rdi
+ lea LOCAL0(%rbp), %rsi
+ mov $8, %rdx
+ call cepis__buf_append
+ test %eax, %eax
+ jnz .Lca_nomem_row
+ jmp .Lca_rows
+.Lca_done:
+ mov CA_ROWS+8(%rbp), %rax
+ shr $3, %rax
+ mov %rax, (%r15)
+ lea CA_ROWS(%rbp), %rdi
+ call cepis__buf_take
+ mov %rax, (%r14)
+ xor %eax, %eax
+ EPILOGUE
+ ret
+.Lca_nomem_row:
+ mov %rbx, %rdi
+ call cepis_address_free
+ jmp .Lca_nomem
+.Lca_nomem_fields:
+ xor %r12d, %r12d
+.Lca_nmf_loop:
+ movslq CA_NF(%rbp), %rax
+ cmp %rax, %r12
+ jae .Lca_nomem
+ mov CA_FIELDS(%rbp, %r12, 8), %rdi
+ call free@PLT
+ inc %r12
+ jmp .Lca_nmf_loop
+.Lca_nomem:
+ mov $CEPIS_ERR_NOMEM, %r13d
+ jmp .Lca_cleanup
+.Lca_invalid:
+ mov $CEPIS_ERR_INVALID_RESPONSE, %r13d
+.Lca_cleanup:
+ mov CA_ROWS(%rbp), %rdi
+ test %rdi, %rdi
+ jz .Lca_cleanup_done
+ mov CA_ROWS+8(%rbp), %rsi
+ shr $3, %rsi
+ call cepis_address_list_free
+ movq $0, CA_ROWS(%rbp)
+.Lca_cleanup_done:
+ mov %r13d, %eax
+ EPILOGUE
+ ret
+ENDFUNC cepis__csv_addresses
+
+ .section .note.GNU-stack,"",@progbits