0
|
1 #include "structs.h"
|
|
2 #include "datum.h"
|
|
3 #include <string.h>
|
|
4 #include <stdio.h>
|
|
5 #include <stdlib.h>
|
|
6
|
|
7 int vis_file_from_string(datum ** inputlist, queue_entry * worker_entry)
|
|
8 {
|
|
9 datum * output;
|
|
10 file_data * file;
|
|
11 output = new_datum(BUILTIN_TYPE_FILE, 1, sizeof(file_data), worker_entry->instance->def->program);
|
|
12 file = output->c.generic.data;
|
|
13 file->shared = malloc(sizeof(shared_file) + inputlist[0]->c.generic.len-1);
|
|
14 strcpy(file->shared->name, inputlist[0]->c.generic.data);
|
|
15 DEBUGPRINTF("File from string name: %s\n", file->shared->name);
|
|
16 release_ref(inputlist[0]);
|
|
17 file->shared->status = FILE_NOSIZE;
|
|
18 VIS_InitializeCriticalSection(file->shared->lock);
|
|
19 file->shared->ref_count = 1;
|
|
20 file->offset = 0;
|
|
21 inputlist[0] = output;
|
|
22 return 0;
|
|
23 }
|
|
24
|
|
25 void vis_file_read_open_check(file_data * file)
|
|
26 {
|
|
27 switch(file->shared->status)
|
|
28 {
|
|
29 case FILE_NOSIZE:
|
|
30 case FILE_CLOSED:
|
|
31 DEBUGPUTS("File is closed, opening...\n");
|
|
32 DEBUGPRINTF("File name: %s\n", file->shared->name);
|
|
33 file->shared->file = fopen(file->shared->name, "rb");
|
|
34 if(!file->shared->file)
|
|
35 {
|
|
36 file->shared->status = FILE_CANT_OPEN;
|
|
37 file->shared->size = 0;
|
|
38 break;
|
|
39 }
|
|
40 if(file->shared->status == FILE_NOSIZE)
|
|
41 {
|
|
42 DEBUGPUTS("Getting file size.\n");
|
|
43 fseek(file->shared->file, 0, SEEK_END);
|
|
44 file->shared->size = ftell(file->shared->file);
|
|
45 DEBUGPRINTF("File size: %d.\n", file->shared->size);
|
|
46 }
|
|
47
|
|
48 file->shared->status = FILE_READ;
|
|
49 break;
|
|
50 default://file is already open
|
|
51 break;
|
|
52 }
|
|
53 DEBUGPRINTF("Seeking to %d\n", file->offset);
|
|
54 if(file->shared->file)
|
|
55 fseek(file->shared->file, file->offset, SEEK_SET);
|
|
56 DEBUGPUTS("Done.\n");
|
|
57 }
|
|
58
|
|
59 int vis_file_get_fstring(datum ** inputlist, queue_entry * worker_entry)
|
|
60 {
|
|
61 file_data * file;
|
|
62 datum * output = new_datum(BUILTIN_TYPE_STRING, 1, inputlist[1]->c.integers.num_a+1, worker_entry->instance->def->program);
|
|
63 inputlist[0] = copy_datum(inputlist[0], 0);
|
|
64 if(inputlist[1]->c.integers.num_a > 0)
|
|
65 {
|
|
66 file = (file_data *)inputlist[0]->c.generic.data;
|
|
67 VIS_EnterCriticalSection(file->shared->lock);
|
|
68 vis_file_read_open_check(file);
|
|
69 fread(output->c.generic.data,1,inputlist[1]->c.integers.num_a, file->shared->file);
|
|
70 VIS_LeaveCriticalSection(file->shared->lock);
|
|
71 file->offset += inputlist[1]->c.integers.num_a;
|
|
72 }
|
|
73 ((char *)output->c.generic.data)[inputlist[1]->c.integers.num_a] = '\0';
|
|
74 release_ref(inputlist[1]);
|
|
75 inputlist[1] = output;
|
|
76 return 0;
|
|
77 }
|
|
78 #define FILE_SEARCH_BUFFER_SIZE 512
|
|
79
|
|
80 typedef struct bufferlist
|
|
81 {
|
|
82 char buffer[FILE_SEARCH_BUFFER_SIZE];
|
|
83 int index;
|
|
84 struct bufferlist * next;
|
|
85 } bufferlist;
|
|
86
|
|
87 int vis_file_get_dstring(datum ** inputlist, queue_entry * worker_entry)
|
|
88 {
|
|
89 BOOL found = FALSE;
|
|
90 bufferlist buffers;
|
|
91 bufferlist * current, *temp,*temp2;
|
|
92 int i,j,k,startk;
|
|
93 int found_entry;
|
|
94 int string_offset;
|
|
95 int search_offset;
|
|
96 bufferlist * search_start;
|
|
97 int search_start_offset;
|
|
98 int *search_offsets;
|
|
99 bufferlist ** search_starts;
|
|
100 int *search_start_offsets;
|
|
101 int read_bytes;
|
|
102
|
|
103 list_data * list;
|
|
104 file_data * file;
|
|
105
|
|
106 inputlist[0] = copy_datum(inputlist[0], 0);
|
|
107 file = (file_data *)inputlist[0]->c.generic.data;
|
|
108 buffers.next = NULL;
|
|
109 DEBUGPUTS("Entering critical section.\n");
|
|
110 VIS_EnterCriticalSection(file->shared->lock);
|
|
111 if(file->offset >= file->shared->size)
|
|
112 {
|
|
113 VIS_LeaveCriticalSection(file->shared->lock);
|
|
114 release_ref(inputlist[0]);
|
|
115 release_ref(inputlist[1]);
|
|
116 inputlist[0] = inputlist[1] = inputlist[2] = NULL;
|
|
117 inputlist[3] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
118 datum_set_yesno(inputlist[3], 1);
|
|
119 return 0;
|
|
120 }
|
|
121 if(inputlist[1]->company->type_id == BUILTIN_TYPE_LIST)
|
|
122 {
|
|
123
|
|
124 list = ((list_data *)inputlist[1]->c.generic.data);
|
|
125 DEBUGPRINTF("Delimeter input is a list with %d entries.\n", list->num_entries);
|
|
126 search_offsets = malloc(sizeof(int) * (list->num_entries));
|
|
127 DEBUGPRINTF("Allocated %d bytes.\n", sizeof(int) * (list->num_entries));
|
|
128 search_starts = malloc(sizeof(bufferlist *) * (list->num_entries));
|
|
129 DEBUGPRINTF("Allocated %d bytes.\n", sizeof(bufferlist *) * (list->num_entries));
|
|
130 search_start_offsets = malloc(sizeof(int) * (list->num_entries));
|
|
131 DEBUGPRINTF("Allocated %d bytes.\n", sizeof(int) * (list->num_entries));
|
|
132 for(i = 0; i < list->num_entries; ++i)
|
|
133 {
|
|
134 DEBUGPRINTF("Setting search_offsets[%d] = 0.\n", i);
|
|
135 search_offsets[i] = 0;
|
|
136 }
|
|
137 }
|
|
138 search_offset = 0;
|
|
139 current = &buffers;
|
|
140 current->index = 0;
|
|
141
|
|
142 DEBUGPUTS("In critical section.\n");
|
|
143 vis_file_read_open_check(file);
|
|
144 DEBUGPUTS("File open.");
|
|
145 while(!found && !feof(file->shared->file))
|
|
146 {
|
|
147 DEBUGPRINTF("Reading %d bytes from file\n", FILE_SEARCH_BUFFER_SIZE);
|
|
148 read_bytes = fread(current->buffer, 1, FILE_SEARCH_BUFFER_SIZE, file->shared->file);
|
|
149 DEBUGPRINTF("fread read %d bytes\n", read_bytes);
|
|
150 for(i = 0; i < read_bytes && !found; ++i)
|
|
151 {
|
|
152 DEBUGPRINTF("Checking character #%d (%c)\n", i, current->buffer[i]);
|
|
153 switch(inputlist[1]->company->type_id)
|
|
154 {
|
|
155 case BUILTIN_TYPE_WHOLE:
|
|
156 if((int)current->buffer[i] == inputlist[1]->c.integers.num_a)
|
|
157 {
|
|
158 found = TRUE;
|
|
159 search_offset = 1;
|
|
160 search_start = current;
|
|
161 search_start_offset = i;
|
|
162 }
|
|
163 break;
|
|
164 case BUILTIN_TYPE_STRING:
|
|
165 if(current->buffer[i] == ((char *)inputlist[1]->c.generic.data)[search_offset])
|
|
166 {
|
|
167 if(search_offset == 0)
|
|
168 {
|
|
169 search_start = current;
|
|
170 search_start_offset = i;
|
|
171 }
|
|
172 ++search_offset;
|
|
173 if(search_offset == (inputlist[1]->c.generic.len-1))
|
|
174 found = TRUE;
|
|
175 }
|
|
176 else
|
|
177 {
|
|
178 if(search_offset > 0)
|
|
179 {
|
|
180 current = search_start;
|
|
181 i = search_start_offset;
|
|
182 }
|
|
183 search_offset = 0;
|
|
184 }
|
|
185 break;
|
|
186 case BUILTIN_TYPE_LIST:
|
|
187 for(j = 0; j < list->num_entries; ++j)
|
|
188 {
|
|
189 DEBUGPRINTF("Testing list entry %d against character %d in buffer %d\n", j, i, current->index);
|
|
190 if(list->entries[j]->company->type_id == BUILTIN_TYPE_WHOLE && (int)current->buffer[i] == list->entries[j]->c.integers.num_a)
|
|
191 {
|
|
192 DEBUGPUTS("Matched whole number entry.\n");
|
|
193 found = TRUE;
|
|
194 found_entry = j;
|
|
195 search_offset = 1;
|
|
196 search_start = current;
|
|
197 search_start_offset = i;
|
|
198 break;
|
|
199 }
|
|
200 else if(list->entries[j]->company->type_id == BUILTIN_TYPE_STRING)
|
|
201 {
|
|
202 DEBUGPUTS("String entry.\n");
|
|
203 if(current->buffer[i] == ((char *)list->entries[j]->c.generic.data)[search_offsets[j]])
|
|
204 {
|
|
205 DEBUGPRINTF("%c in buffer matches character #%d in entry.\n", current->buffer[i], search_offsets[j]);
|
|
206 if(search_offsets[j] == 0)
|
|
207 {
|
|
208 search_starts[j] = current;
|
|
209 search_start_offsets[j] = i;
|
|
210 }
|
|
211 ++search_offsets[j];
|
|
212 if(search_offsets[j] == (list->entries[j]->c.generic.len-1))
|
|
213 {
|
|
214 DEBUGPUTS("Entire string matched.\n");
|
|
215 found = TRUE;
|
|
216 found_entry = j;
|
|
217 search_offset = search_offsets[j];
|
|
218 search_start = search_starts[j];
|
|
219 search_start_offset = search_start_offsets[j];
|
|
220 break;
|
|
221 }
|
|
222 }
|
|
223 else if(search_offsets[j] > 0)
|
|
224 {
|
|
225 DEBUGPRINTF("%c in bufer does not match character #%d in entry.\n", current->buffer[i], search_offsets[j]);
|
|
226 temp = search_starts[j];
|
|
227 search_offsets[j] = 0;
|
|
228 startk = search_start_offsets[j];
|
|
229 while(temp && !found)
|
|
230 {
|
|
231 DEBUGPRINTF("Scanning block %d for possible missed match from %d to %d.\n", temp->index, startk, (temp == current ? i : FILE_SEARCH_BUFFER_SIZE)-1);
|
|
232 for(k = startk; k < (temp == current ? i : FILE_SEARCH_BUFFER_SIZE); ++k)
|
|
233 {
|
|
234 if(temp->buffer[k] == ((char *)list->entries[j]->c.generic.data)[search_offsets[j]])
|
|
235 {
|
|
236 if(!search_offsets[j])
|
|
237 {
|
|
238 search_starts[j] = temp;
|
|
239 search_start_offsets[j] = k;
|
|
240 }
|
|
241 ++search_offsets[j];
|
|
242 if(search_offset == (list->entries[j]->c.generic.len-1))
|
|
243 {
|
|
244 found = TRUE;
|
|
245 found_entry = j;
|
|
246 search_start = search_starts[j];
|
|
247 search_start_offset = search_start_offsets[j];
|
|
248 }
|
|
249 }
|
|
250 else
|
|
251 {
|
|
252 if(search_offsets[j] > 0)
|
|
253 {
|
|
254 temp = search_starts[j];
|
|
255 k = search_start_offsets[j];
|
|
256 }
|
|
257 search_offsets[j] = 0;
|
|
258 }
|
|
259 }
|
|
260 startk = 0;
|
|
261 temp = temp->next;
|
|
262 }
|
|
263
|
|
264 }
|
|
265 else
|
|
266 search_offsets[j] = 0;
|
|
267
|
|
268 }
|
|
269 }
|
|
270 break;
|
|
271 }
|
|
272 }
|
|
273 if(!found && !feof(file->shared->file))
|
|
274 {
|
|
275 current->next = malloc(sizeof(bufferlist));
|
|
276 DEBUGPRINTF("Allocated next buffer at %X (%d bytes)\n", current->next, sizeof(bufferlist));
|
|
277 current->next->index = current->index+1;
|
|
278 current->next->next = NULL;
|
|
279 current = current->next;
|
|
280 }
|
|
281 }
|
|
282 VIS_LeaveCriticalSection(file->shared->lock);
|
|
283 if(inputlist[1]->company->type_id == BUILTIN_TYPE_LIST)
|
|
284 {
|
|
285 VIS_FREE(search_offsets, "Get DString@File, search offsets");
|
|
286 VIS_FREE(search_starts, "Get DString@File, search starts");
|
|
287 VIS_FREE(search_start_offsets, "Get DString@File, search start offsets");
|
|
288 }
|
|
289 if(found)
|
|
290 {
|
|
291 DEBUGPUTS("Found a delimeter");
|
|
292 if(inputlist[1]->company->type_id == BUILTIN_TYPE_LIST)
|
|
293 {
|
|
294 inputlist[2] = add_ref(list->entries[found_entry]);
|
|
295 release_ref(inputlist[1]);
|
|
296 }
|
|
297 else
|
|
298 inputlist[2] = inputlist[1];
|
|
299 inputlist[3] = NULL;
|
|
300 }
|
|
301 else
|
|
302 {
|
|
303 DEBUGPUTS("Didn't find a delimeter");
|
|
304 release_ref(inputlist[1]);
|
|
305 inputlist[2] = NULL;
|
|
306 inputlist[3] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
307 datum_set_yesno(inputlist[3], 0);
|
|
308 }
|
|
309 //Does this need to be here still or was it just working around another bug?
|
|
310 if(search_start_offset < 0)
|
|
311 search_start_offset = 0;
|
|
312 if(!found) {
|
|
313 search_start = current;
|
|
314 search_start_offset = i;
|
|
315 }
|
|
316 if(found)
|
|
317 {
|
|
318 inputlist[1] = new_datum(BUILTIN_TYPE_STRING, 1, FILE_SEARCH_BUFFER_SIZE * current->index + search_start_offset+1, worker_entry->instance->def->program);
|
|
319 //file->offset += FILE_SEARCH_BUFFER_SIZE * current->index + search_start_offset + search_offset;
|
|
320 file->offset += FILE_SEARCH_BUFFER_SIZE * search_start->index + search_start_offset + search_offset;
|
|
321 }
|
|
322 else
|
|
323 {
|
|
324 inputlist[1] = new_datum(BUILTIN_TYPE_STRING, 1, FILE_SEARCH_BUFFER_SIZE * current->index + read_bytes+1, worker_entry->instance->def->program);
|
|
325 file->offset += FILE_SEARCH_BUFFER_SIZE * current->index + read_bytes;
|
|
326 }
|
|
327 temp = &buffers;
|
|
328 string_offset = 0;
|
|
329 while(temp)
|
|
330 {
|
|
331 DEBUGPRINTF("Copying from index %d to offset %X\n", temp->index, string_offset);
|
|
332 if(temp == search_start)
|
|
333 {
|
|
334 //if(found)
|
|
335 //{
|
|
336 temp->buffer[search_start_offset] = '\0';
|
|
337 memcpy(((char *)inputlist[1]->c.generic.data)+string_offset, temp->buffer, search_start_offset);
|
|
338 string_offset += search_start_offset;
|
|
339 /*}
|
|
340 else
|
|
341 {
|
|
342 memcpy(((char *)inputlist[1]->c.generic.data)+string_offset, temp->buffer, i);
|
|
343 string_offset += i;
|
|
344 }*/
|
|
345 break;
|
|
346 }
|
|
347 else
|
|
348 {
|
|
349 memcpy(((char *)inputlist[1]->c.generic.data)+string_offset, temp->buffer, FILE_SEARCH_BUFFER_SIZE);
|
|
350 string_offset += FILE_SEARCH_BUFFER_SIZE;
|
|
351 }
|
|
352 if(temp != &buffers)
|
|
353 {
|
|
354 temp2 = temp->next;
|
|
355 VIS_FREE(temp, "Get DString@File, buffer node");
|
|
356 temp = temp2;
|
|
357 }
|
|
358 else
|
|
359 temp = temp->next;
|
|
360 }
|
|
361 while(temp)
|
|
362 {
|
|
363 if(temp != &buffers)
|
|
364 {
|
|
365 temp2 = temp->next;
|
|
366 DEBUGPRINTF("Freeing %X\n", temp);
|
|
367 VIS_FREE(temp, "Get DString@File, buffer node");
|
|
368 temp = temp2;
|
|
369 }
|
|
370 else
|
|
371 temp = temp->next;
|
|
372 }
|
|
373 ((char *)inputlist[1]->c.generic.data)[string_offset] = '\0';
|
|
374 DEBUGPRINTF("Output string: %s\n", inputlist[1]->c.generic.data);
|
|
375 return 0;
|
|
376 }
|
|
377
|
|
378 int vis_file_get_byte(datum ** inputlist, queue_entry * worker_entry)
|
|
379 {
|
|
380 file_data * file;
|
|
381 BOOL eof;
|
|
382 char num;
|
|
383
|
|
384 inputlist[0] = copy_datum(inputlist[0], 0);
|
|
385 file = (file_data *)inputlist[0]->c.generic.data;
|
|
386 VIS_EnterCriticalSection(file->shared->lock);
|
|
387 if(!(eof = (file->offset >= file->shared->size)))
|
|
388 {
|
|
389 vis_file_read_open_check(file);
|
|
390 fread(&num,sizeof(char),1, file->shared->file);
|
|
391 }
|
|
392 VIS_LeaveCriticalSection(file->shared->lock);
|
|
393 if(eof)
|
|
394 {
|
|
395 release_ref(inputlist[0]);
|
|
396 inputlist[0] = inputlist[1] = NULL;
|
|
397 inputlist[2] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
398 datum_set_yesno(inputlist[2], 1);
|
|
399 }
|
|
400 else
|
|
401 {
|
|
402 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
|
|
403 inputlist[1]->c.integers.num_a = num;
|
|
404 inputlist[2] = NULL;
|
|
405 file->offset += sizeof(char);
|
|
406 }
|
|
407 return 0;
|
|
408 }
|
|
409
|
|
410 int vis_file_get_word(datum ** inputlist, queue_entry * worker_entry)
|
|
411 {
|
|
412 file_data * file;
|
|
413 BOOL eof;
|
|
414 short num;
|
|
415
|
|
416 inputlist[0] = copy_datum(inputlist[0], 0);
|
|
417 file = (file_data *)inputlist[0]->c.generic.data;
|
|
418 VIS_EnterCriticalSection(file->shared->lock);
|
|
419 if(!(eof = (file->offset >= file->shared->size)))
|
|
420 {
|
|
421 vis_file_read_open_check(file);
|
|
422 fread(&num,sizeof(short),1, file->shared->file);
|
|
423 }
|
|
424 VIS_LeaveCriticalSection(file->shared->lock);
|
|
425 if(eof)
|
|
426 {
|
|
427 release_ref(inputlist[0]);
|
|
428 inputlist[0] = inputlist[1] = NULL;
|
|
429 inputlist[2] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
430 datum_set_yesno(inputlist[2], 1);
|
|
431 }
|
|
432 else
|
|
433 {
|
|
434 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
|
|
435 inputlist[1]->c.integers.num_a = num;
|
|
436 inputlist[2] = NULL;
|
|
437 file->offset += sizeof(short);
|
|
438 }
|
|
439 return 0;
|
|
440 }
|
|
441
|
|
442 int vis_file_get_long(datum ** inputlist, queue_entry * worker_entry)
|
|
443 {
|
|
444 file_data * file;
|
|
445 BOOL eof;
|
|
446 long num;
|
|
447
|
|
448 inputlist[0] = copy_datum(inputlist[0], 0);
|
|
449 file = (file_data *)inputlist[0]->c.generic.data;
|
|
450 VIS_EnterCriticalSection(file->shared->lock);
|
|
451 if(!(eof = (file->offset >= file->shared->size)))
|
|
452 {
|
|
453 vis_file_read_open_check(file);
|
|
454 fread(&num,sizeof(long),1, file->shared->file);
|
|
455 }
|
|
456 VIS_LeaveCriticalSection(file->shared->lock);
|
|
457 if(eof)
|
|
458 {
|
|
459 release_ref(inputlist[0]);
|
|
460 inputlist[0] = inputlist[1] = NULL;
|
|
461 inputlist[2] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
462 datum_set_yesno(inputlist[2], 1);
|
|
463 }
|
|
464 else
|
|
465 {
|
|
466 inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
|
|
467 inputlist[1]->c.integers.num_a = num;
|
|
468 inputlist[2] = NULL;
|
|
469 file->offset += sizeof(long);
|
|
470 }
|
|
471 return 0;
|
|
472 }
|
|
473
|
|
474 void vis_file_write_open_check(file_data * file)
|
|
475 {
|
|
476 switch(file->shared->status)
|
|
477 {
|
|
478 case FILE_READ:
|
|
479 fclose(file->shared->file);
|
|
480 case FILE_NOSIZE:
|
|
481 case FILE_CLOSED:
|
|
482 DEBUGPUTS("File is closed, opening...\n");
|
|
483 DEBUGPRINTF("File name: %s\n", file->shared->name);
|
|
484 file->shared->file = fopen(file->shared->name, "r+b");
|
|
485 if(!file->shared->file)
|
|
486 file->shared->file = fopen(file->shared->name,"w+b");
|
|
487 if(!file->shared->file)
|
|
488 {
|
|
489 file->shared->status = FILE_CANT_OPEN;
|
|
490 file->shared->size = 0;
|
|
491 break;
|
|
492 }
|
|
493 if(file->shared->status == FILE_NOSIZE)
|
|
494 {
|
|
495 DEBUGPUTS("Getting file size.\n");
|
|
496 fseek(file->shared->file, 0, SEEK_END);
|
|
497 file->shared->size = ftell(file->shared->file);
|
|
498 DEBUGPRINTF("File size: %d.\n", file->shared->size);
|
|
499 }
|
|
500
|
|
501 file->shared->status = FILE_WRITE;
|
|
502 break;
|
|
503 default://file is already open
|
|
504 break;
|
|
505 }
|
|
506 DEBUGPRINTF("Seeking to %d\n", file->offset);
|
|
507 if(file->shared->file)
|
|
508 fseek(file->shared->file, file->offset, SEEK_SET);
|
|
509 DEBUGPUTS("Done.\n");
|
|
510 }
|
|
511
|
|
512 int vis_file_put_string(datum ** inputlist, queue_entry * worker_entry)
|
|
513 {
|
|
514 file_data * file;
|
|
515 int written;
|
|
516 inputlist[0] = copy_datum(inputlist[0], 0);
|
|
517 file = ((file_data *)inputlist[0]->c.generic.data);
|
|
518 VIS_EnterCriticalSection(file->shared->lock);
|
|
519 vis_file_write_open_check(file);
|
|
520 written = fwrite(inputlist[1]->c.generic.data,1,inputlist[1]->c.generic.len-1,file->shared->file);
|
|
521 file->offset += written;
|
|
522 if(file->offset > file->shared->size)
|
|
523 file->shared->size = file->offset;
|
|
524 VIS_LeaveCriticalSection(file->shared->lock);
|
|
525 release_ref(inputlist[1]);
|
|
526 return 0;
|
|
527 }
|
|
528
|
|
529 int vis_file_length(datum ** inputlist, queue_entry * worker_entry)
|
|
530 {
|
|
531 file_data * file;
|
|
532 int written;
|
|
533 int size;
|
|
534 file = ((file_data *)inputlist[0]->c.generic.data);
|
|
535 VIS_EnterCriticalSection(file->shared->lock);
|
|
536 vis_file_read_open_check(file);
|
|
537 size = file->shared->size;
|
|
538 VIS_LeaveCriticalSection(file->shared->lock);
|
|
539 release_ref(inputlist[0]);
|
|
540 inputlist[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
|
|
541 inputlist[0]->c.integers.num_a = size;
|
|
542 return 0;
|
|
543 }
|