1
+ package csv
2
+
3
+ /*
4
+ #include <stdlib.h>
5
+ */
6
+ import "C"
7
+ import (
8
+ "encoding/csv"
9
+ "encoding/json"
10
+ "os"
11
+ "strings"
12
+ )
13
+
14
+ // CSVData represents structured CSV output.
15
+ type CSVData struct {
16
+ Headers []string `json:"headers"`
17
+ Rows [][]string `json:"rows"`
18
+ }
19
+
20
+ //export LoadCSV
21
+ func (c * CSVData ) LoadCSV (filePath * C.char ) * C.char {
22
+
23
+ goFilePath := C .GoString (filePath )
24
+ file , err := os .Open (goFilePath )
25
+
26
+ if err != nil {
27
+ return C .CString (`{"error": "CSV File Not Found"}` )
28
+ }
29
+ defer file .Close ()
30
+
31
+ reader := csv .NewReader (file )
32
+
33
+ // Read headers
34
+ headers , err := reader .Read ()
35
+ if err != nil {
36
+ return C .CString (`{"error": "Failed to read headers"}` )
37
+ }
38
+ headers = trimSpaces (headers )
39
+
40
+ // ! STORE THE CSV FILE HEADERS IN MEMORY FOR DOING REDUNDANT FILE-IO
41
+ c .Headers = headers
42
+
43
+ // Read rows
44
+ var rows [][]string
45
+ records , err := reader .ReadAll ()
46
+ if err != nil {
47
+ return C .CString (`{"error": "Failed to read rows"}` )
48
+ }
49
+
50
+ for _ , record := range records {
51
+
52
+ row := trimSpaces (record )
53
+
54
+ if allEmpty (row ) {
55
+ continue
56
+ }
57
+
58
+ // Fill missing values
59
+ for len (row ) < len (headers ) {
60
+ row = append (row , "N/A" )
61
+ }
62
+
63
+ if len (row ) > len (headers ) {
64
+ row = row [:len (headers )]
65
+ }
66
+
67
+ rows = append (rows , row )
68
+ }
69
+
70
+ // ! STORE THE CSV FILE HEADERS IN MEMORY FOR DOING REDUNDANT FILE-IO
71
+ c .Rows = rows
72
+
73
+ // Convert to JSON
74
+ csvData := CSVData {Headers : headers , Rows : rows }
75
+ jsonData , _ := json .Marshal (csvData )
76
+
77
+ // Return JSON as C string
78
+ return C .CString (string (jsonData ))
79
+ }
80
+
81
+ //export filterRows
82
+ func (c * CSVData ) filterRows (column * C.char , condition * C.char , writeToFile * C.int , outputFile * C.char ) * * C.char {
83
+ goColumn := C .GoString (column )
84
+ goCondition := C .GoString (condition )
85
+ goOutputFile := C .GoString (outputFile )
86
+ writeToFileFlag := int (writeToFile ) != 0
87
+
88
+ // Find column index
89
+ colIdx := - 1
90
+ for i , h := range c .Headers {
91
+ if strings .TrimSpace (h ) == goColumn {
92
+ colIdx = i
93
+ break
94
+ }
95
+ }
96
+
97
+ if colIdx == - 1 {
98
+ return nil // Column not found
99
+ }
100
+
101
+ // Filter rows
102
+ filteredRows := [][]string {c .Headers }
103
+ for _ , row := range c .Rows {
104
+ if colIdx < len (row ) && row [colIdx ] == goCondition {
105
+ filteredRows = append (filteredRows , row )
106
+ }
107
+ }
108
+
109
+ // Write to file if required
110
+ if writeToFileFlag {
111
+ outFile , err := os .Create (goOutputFile )
112
+ if err == nil {
113
+ defer outFile .Close ()
114
+ writer := csv .NewWriter (outFile )
115
+ writer .WriteAll (filteredRows )
116
+ writer .Flush ()
117
+ }
118
+ }
119
+
120
+ // Convert to C-compatible char array
121
+ result := make ([]* C.char , len (filteredRows ))
122
+ for i , row := range filteredRows {
123
+ result [i ] = C .CString (strings .Join (row , "," ))
124
+ }
125
+
126
+ return & result [0 ]
127
+ }
128
+
129
+ func trimSpaces (s []string ) []string {
130
+ for i , v := range s {
131
+ s [i ] = strings .TrimSpace (v )
132
+ }
133
+ return s
134
+ }
135
+
136
+ func allEmpty (row []string ) bool {
137
+ for _ , cell := range row {
138
+ if cell != "" {
139
+ return false
140
+ }
141
+ }
142
+ return true
143
+ }
144
+
145
+ func main () {}
0 commit comments