-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsv.cpp
238 lines (202 loc) · 6.96 KB
/
csv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*****************************************************************************/
/** Lector de ficheros CSV para DIV2 **/
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Tipos de tamaØo predeterminado */
#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#else
#include "myint.h"
#endif
#include "csv.h"
#define GLOBALS
#include "div.h"
INIT_LOG();
#define BUFFER_SIZE 256
#define EOL "\r\n"
/**
* Tama¤o del tipo de dato
*/
typedef enum {
BYTE,
WORD,
INT
} DataSize;
uint_8_t isValueSeparatorWithEOLFilled = 0; // Flag para saber si ya hemos rellenado valueSeparatorWithEOL
char* valueSeparator = ",";
char valueSeparatorWithEOL[BUFFER_SIZE]; // El elemento separador concatenado con EOL
void dropBufferFrom(char *buf,char dropCharacter);
void tokenizeLine(DataSize dataSize, char *buf, uint_32_t offset, uint_32_t numberOfElements, uint_32_t *index);
void putValueInt(const char *token, uint_32_t offset, uint_32_t index);
void putValueWord(const char *token, uint_32_t offset, uint_32_t index);
void putValueByte(const char *token, uint_32_t offset, uint_32_t index);
/**
* Elimina del buf todo el contenido posterior a un caracter si este est?
* presente
* @param buf Ptr. al buf
* @param dropCharacter Caracter a buscar el punto desde donde eliminar
*/
void dropBufferFrom(char *buf,char dropCharacter)
{
char* position = strchr(buf, dropCharacter);
if (position != NULL) {
// Insertamos un caracter nulo en dicha posici®n para "cortar" la cadena por ahi
*position = 0;
}
}
/**
* Tokeniza el buf usando el separador ';' y procesa cada token
* @param dataSize Tama¤o del tipo de dato
* @param buf Ptr. al buf
* @param offset Offset del array de Ints de DIV
* @param numberOfElements N? maximo de elementos del array
* @param *index Indice del elemento del array a guardar
*/
void tokenizeLine(DataSize dataSize, char *buf, uint_32_t offset, uint_32_t numberOfElements, uint_32_t *index)
{
const char* token = strtok(buf, valueSeparator);
while (*index < numberOfElements && token != NULL && *token != 0) {
if (offset != 0) {
switch (dataSize) {
case BYTE:
putValueByte(token, offset, *index);
break;
case WORD:
putValueWord(token, offset, *index);
break;
case INT:
default:
putValueInt(token, offset, *index);
}
}
token = strtok(NULL, valueSeparatorWithEOL);
// El indice lo aumentamos desde aqui para contar solo los tokens validos
*index = *index + 1;
}
}
/**
* Mete un valor int 32bits en la memoria de DIV
*/
void putValueInt(const char *token, uint_32_t offset, uint_32_t index)
{
int_32_t val = 0;
int_32_t* ptr = &mem[offset];
if (token != NULL) {
val = (int_32_t) strtol(token, NULL, 0);
// mem es un array de int_32_t con toda la memoria del programa DIV
// si DIV2 esta compactando cuando el tipo del array es byte o word, entonces
// habra que hacer magia con punteros
ptr[index] = val;
}
}
/**
* Mete un valor word 16bit en la memoria de DIV
*/
void putValueWord(const char *token, uint_32_t offset, uint_32_t index)
{
int_16_t val = 0;
int_16_t* ptr = (int_16_t*) &mem[offset];
if (token != NULL) {
val = (int_16_t) strtol(token, NULL, 0);
ptr[index] = val;
}
}
/**
* Mete un valor byte en la memoria de DIV
*/
void putValueByte(const char *token, uint_32_t offset, uint_32_t index)
{
int_8_t val = 0;
int_8_t* ptr = (int_8_t*) &mem[offset];
if (token != NULL) {
val = (int_8_t) strtol(token, NULL, 0);
ptr[index] = val;
}
}
// Importante: Para cada funci¢n se debe indicar el retval(int), y hacer
// siempre un getparm() por cada par metro de llamada (el retval() es
// imprescindible incluso si la funci¢n no necesita devolver un valor).
inline void readCSVToArray(DataSize dataSize) {
char* fileName = NULL;
FILE *file = NULL;
char buf[BUFFER_SIZE];
int error = 0;
uint_32_t index = 0;
// Rellenamos valueSeparatorWithEOL de forma lazy
if (!isValueSeparatorWithEOLFilled) {
sprintf(valueSeparatorWithEOL, "%s%s", valueSeparator, EOL);
isValueSeparatorWithEOLFilled = 1;
}
OPEN_LOG();
// Los par metros se leen en el orden inverso en que se declaran, al
// provenir del stack del interprete de DIV
int numberOfElements = getparm();
int offset = getparm();
int offsetFileName = getparm();
// Obtenermos el texto en el array, a partir del bloque de textos + el offset que nos pasa DIV
fileName = (char *)&mem[text_offset + offsetFileName];
LPRINTF("CSV: nElem = %d\n", numberOfElements);
LPRINTF("CSV: offset = %d\n", offset);
LPRINTF("CSV: fileName = %s\n", fileName);
memset(buf, 0, BUFFER_SIZE * sizeof(char));
file = div_fopen(fileName, "r");
if (file != NULL) {
LPRINT("CSV: fopen\n");
while (index < numberOfElements && fgets(buf, BUFFER_SIZE-1, file ) != NULL) {
dropBufferFrom(buf, '\r');
dropBufferFrom(buf, '\n'); // Purgar fin de linea CRLF o LF
dropBufferFrom(buf, '#'); // Comentarios
LPRINTF("CSV: buf=%s\n", buf);
tokenizeLine(dataSize, buf, offset, numberOfElements, &index);
}
div_fclose(file);
} else {
LPRINT("CSV: file not opened or found\n");
retval(-1);
return;
}
LPRINTF("CSV: index=%d\n", index);
CLOSE_LOG();
retval(index);
}
extern "C" {
// Funci¢n DIV readCSVToIntArray(string fileName ,offset array, numberOfElements)
void readCSVToIntArray() {
readCSVToArray(INT);
}
// Funci¢n DIV readCSVToWordArray(string fileName ,offset array, numberOfElements)
void readCSVToWordArray() {
readCSVToArray(WORD);
}
// Funci¢n DIV readCSVToByteArray(string fileName ,offset array, numberOfElements)
void readCSVToByteArray() {
readCSVToArray(BYTE);
}
// Funci¢n DIV setCSVSeparator(string separator)
void setCSVSeparator() {
int offsetSeparator = getparm();
char* divString = (char *)&mem[text_offset + offsetSeparator];
size_t stringLenght = strlen(divString);
if (stringLenght <= 0) {
retval(-1); // No se ha pasado una cadena valida
return;
}
valueSeparator = divString;
sprintf(valueSeparatorWithEOL, "%s%s", valueSeparator, EOL);
isValueSeparatorWithEOLFilled = 1;
retval(0);
}
void __export divlibrary(LIBRARY_PARAMS) {
// Nombre en DIV, ptr a funci¢n, n§ de par metros
COM_export("readCSVToIntArray", readCSVToIntArray, 3);
COM_export("readCSVToWordArray", readCSVToWordArray, 3);
COM_export("readCSVToByteArray", readCSVToByteArray, 3);
COM_export("setCSVSeparator", setCSVSeparator, 1);
}
void __export divmain(COMMON_PARAMS) {
GLOBAL_IMPORT();
}
}
/* vim: set ts=2 sw=2 tw=0 et fileencoding=cp858 :*/