@@ -13,6 +13,7 @@ typedef struct THDiskFile__
13
13
FILE *handle;
14
14
char *name;
15
15
int isNativeEncoding;
16
+ int longSize;
16
17
17
18
} THDiskFile;
18
19
@@ -172,9 +173,17 @@ static void THDiskFile_seek(THFile *self, long position)
172
173
THDiskFile *dfself = (THDiskFile*)(self);
173
174
174
175
THArgCheck (dfself->handle != NULL , 1 , " attempt to use a closed file" );
175
- THArgCheck (position >= 0 , 2 , " position must be positive" );
176
176
177
- if (fseek (dfself->handle , position, SEEK_SET) < 0 )
177
+ #if defined(_WIN64)
178
+ THArgCheck (position <= (_int64)INT64_MAX, 2 , " position must be smaller than INT64_MAX" );
179
+ if (_fseeki64 (dfself->handle , (__int64)position, SEEK_SET) < 0 )
180
+ #elif defined(_WIN32)
181
+ THArgCheck (position <= (long )LONG_MAX, 2 , " position must be smaller than LONG_MAX" );
182
+ if (fseek (dfself->handle , (long )position, SEEK_SET) < 0 )
183
+ #else
184
+ THArgCheck (position <= (long )LLONG_MAX, 2 , " position must be smaller than LLONG_MAX" );
185
+ if (fseeko (dfself->handle , (off_t )position, SEEK_SET) < 0 )
186
+ #endif
178
187
{
179
188
dfself->file .hasError = 1 ;
180
189
if (!dfself->file .isQuiet )
@@ -188,7 +197,13 @@ static void THDiskFile_seekEnd(THFile *self)
188
197
189
198
THArgCheck (dfself->handle != NULL , 1 , " attempt to use a closed file" );
190
199
200
+ #if defined(_WIN64)
201
+ if (_fseeki64 (dfself->handle , 0L , SEEK_END) < 0 )
202
+ #elif defined(_WIN32)
191
203
if (fseek (dfself->handle , 0L , SEEK_END) < 0 )
204
+ #else
205
+ if (fseeko (dfself->handle , 0L , SEEK_END) < 0 )
206
+ #endif
192
207
{
193
208
dfself->file .hasError = 1 ;
194
209
if (!dfself->file .isQuiet )
@@ -200,7 +215,20 @@ static long THDiskFile_position(THFile *self)
200
215
{
201
216
THDiskFile *dfself = (THDiskFile*)(self);
202
217
THArgCheck (dfself->handle != NULL , 1 , " attempt to use a closed file" );
203
- return ftell (dfself->handle );
218
+
219
+ #if defined(_WIN64)
220
+ __int64 offset = _ftelli64 (dfself->handle );
221
+ #elif defined(_WIN32)
222
+ long offset = ftell (dfself->handle );
223
+ #else
224
+ off_t offset = ftello (dfself->handle );
225
+ #endif
226
+ if (offset > -1 )
227
+ return (long )offset;
228
+ else if (!dfself->file .isQuiet )
229
+ THError (" unable to obtain disk file offset (maybe a long overflow occurred)" );
230
+
231
+ return 0 ;
204
232
}
205
233
206
234
static void THDiskFile_close (THFile *self)
@@ -274,6 +302,23 @@ void THDiskFile_bigEndianEncoding(THFile *self)
274
302
275
303
/* End of Little and Big Endian Stuff */
276
304
305
+ void THDiskFile_longSize (THFile *self, int size)
306
+ {
307
+ THDiskFile *dfself = (THDiskFile*)(self);
308
+ THArgCheck (dfself->handle != NULL , 1 , " attempt to use a closed file" );
309
+ THArgCheck (size == 0 || size == 4 || size == 8 , 1 , " Invalid long size specified" );
310
+ dfself->longSize = size;
311
+ }
312
+
313
+ void THDiskFile_noBuffer (THFile *self)
314
+ {
315
+ THDiskFile *dfself = (THDiskFile*)(self);
316
+ THArgCheck (dfself->handle != NULL , 1 , " attempt to use a closed file" );
317
+ if (setvbuf (dfself->handle , NULL , _IONBF, 0 )) {
318
+ THError (" error: cannot disable buffer" );
319
+ }
320
+ }
321
+
277
322
static void THDiskFile_free (THFile *self)
278
323
{
279
324
THDiskFile *dfself = (THDiskFile*)(self);
@@ -302,12 +347,12 @@ READ_WRITE_METHODS(short, Short,
302
347
int ret = fprintf(dfself->handle, " %hd" , data[i]); if (ret <= 0 ) break ; else nwrite++)
303
348
304
349
READ_WRITE_METHODS (int , Int,
305
- int ret = fscanf(dfself->handle, " %d" , &data[i]); if (ret <= 0 ) break ; else nread++,
350
+ int ret = fscanf(dfself->handle, " %d\n\r " , &data[i]); if (ret <= 0 ) break ; else nread++,
306
351
int ret = fprintf(dfself->handle, " %d" , data[i]); if (ret <= 0 ) break ; else nwrite++)
307
352
308
- READ_WRITE_METHODS (long , Long,
353
+ /* READ_WRITE_METHODS(long, Long,
309
354
int ret = fscanf(dfself->handle, "%ld", &data[i]); if(ret <= 0) break; else nread++,
310
- int ret = fprintf(dfself->handle, " %ld" , data[i]); if (ret <= 0 ) break ; else nwrite++)
355
+ int ret = fprintf(dfself->handle, "%ld", data[i]); if(ret <= 0) break; else nwrite++)*/
311
356
312
357
READ_WRITE_METHODS (float , Float,
313
358
int ret = fscanf(dfself->handle, " %g" , &data[i]); if (ret <= 0 ) break ; else nread++,
@@ -317,6 +362,146 @@ READ_WRITE_METHODS(double, Double,
317
362
int ret = fscanf(dfself->handle, " %lg" , &data[i]); if (ret <= 0 ) break ; else nread++,
318
363
int ret = fprintf(dfself->handle, " %.17g" , data[i]); if (ret <= 0 ) break ; else nwrite++)
319
364
365
+
366
+ /* For Long we need to rewrite everything, because of the special management of longSize */
367
+ static long THDiskFile_readLong (THFile *self, int64 *data, long n)
368
+ {
369
+ THDiskFile *dfself = (THDiskFile*)(self);
370
+ long nread = 0L ;
371
+
372
+ THArgCheck (dfself->handle != NULL , 1 , " attempt to use a closed file" );
373
+ THArgCheck (dfself->file .isReadable , 1 , " attempt to read in a write-only file" );
374
+
375
+ if (dfself->file .isBinary )
376
+ {
377
+ if (dfself->longSize == 0 || dfself->longSize == sizeof (int64))
378
+ {
379
+ nread = fread__ (data, sizeof (int64), n, dfself->handle );
380
+ if (!dfself->isNativeEncoding && (sizeof (int64) > 1 ) && (nread > 0 ))
381
+ THDiskFile_reverseMemory (data, data, sizeof (int64), nread);
382
+ } else if (dfself->longSize == 4 )
383
+ {
384
+ nread = fread__ (data, 4 , n, dfself->handle );
385
+ if (!dfself->isNativeEncoding && (nread > 0 ))
386
+ THDiskFile_reverseMemory (data, data, 4 , nread);
387
+ long i;
388
+ for (i = nread; i > 0 ; i--)
389
+ data[i-1 ] = ((int *)data)[i-1 ];
390
+ }
391
+ else /* if(dfself->longSize == 8) */
392
+ {
393
+ int big_endian = !THDiskFile_isLittleEndianCPU ();
394
+ int32_t *buffer = (int32_t *)THAlloc (8 *n);
395
+ nread = fread__ (buffer, 8 , n, dfself->handle );
396
+ long i;
397
+ for (i = nread; i > 0 ; i--)
398
+ data[i-1 ] = buffer[2 *(i-1 ) + big_endian];
399
+ THFree (buffer);
400
+ if (!dfself->isNativeEncoding && (nread > 0 ))
401
+ THDiskFile_reverseMemory (data, data, 4 , nread);
402
+ }
403
+ }
404
+ else
405
+ {
406
+ long i;
407
+ for (i = 0 ; i < n; i++)
408
+ {
409
+ long d;
410
+ int ret = fscanf (dfself->handle , " %ld" , &d); if (ret <= 0 ) break ; else nread++;
411
+ data[i] = d;
412
+ }
413
+ if (dfself->file .isAutoSpacing && (n > 0 ))
414
+ {
415
+ int c = fgetc (dfself->handle );
416
+ if ( (c != ' \n ' ) && (c != EOF) )
417
+ ungetc (c, dfself->handle );
418
+ }
419
+ }
420
+
421
+ if (nread != n)
422
+ {
423
+ dfself->file .hasError = 1 ; /* shouldn't we put hasError to 0 all the time ? */
424
+ if (!dfself->file .isQuiet )
425
+ THError (" read error: read %d blocks instead of %d" , nread, n);
426
+ }
427
+
428
+ return nread;
429
+ }
430
+
431
+ static long THDiskFile_writeLong (THFile *self, int64 *data, long n)
432
+ {
433
+ THDiskFile *dfself = (THDiskFile*)(self);
434
+ long nwrite = 0L ;
435
+
436
+ THArgCheck (dfself->handle != NULL , 1 , " attempt to use a closed file" );
437
+ THArgCheck (dfself->file .isWritable , 1 , " attempt to write in a read-only file" );
438
+
439
+ if (dfself->file .isBinary )
440
+ {
441
+ if (dfself->longSize == 0 || dfself->longSize == sizeof (long ))
442
+ {
443
+ if (dfself->isNativeEncoding )
444
+ {
445
+ nwrite = fwrite (data, sizeof (long ), n, dfself->handle );
446
+ }
447
+ else
448
+ {
449
+ char *buffer = (char *)THAlloc (sizeof (long )*n);
450
+ THDiskFile_reverseMemory (buffer, data, sizeof (long ), n);
451
+ nwrite = fwrite (buffer, sizeof (long ), n, dfself->handle );
452
+ THFree (buffer);
453
+ }
454
+ } else if (dfself->longSize == 4 )
455
+ {
456
+ int32_t *buffer = (int32_t *)THAlloc (4 *n);
457
+ long i;
458
+ for (i = 0 ; i < n; i++)
459
+ buffer[i] = data[i];
460
+ if (!dfself->isNativeEncoding )
461
+ THDiskFile_reverseMemory (buffer, buffer, 4 , n);
462
+ nwrite = fwrite (buffer, 4 , n, dfself->handle );
463
+ THFree (buffer);
464
+ }
465
+ else /* if(dfself->longSize == 8) */
466
+ {
467
+ int big_endian = !THDiskFile_isLittleEndianCPU ();
468
+ int32_t *buffer = (int32_t *)THAlloc (8 *n);
469
+ long i;
470
+ for (i = 0 ; i < n; i++)
471
+ {
472
+ buffer[2 *i + !big_endian] = 0 ;
473
+ buffer[2 *i + big_endian] = data[i];
474
+ }
475
+ if (!dfself->isNativeEncoding )
476
+ THDiskFile_reverseMemory (buffer, buffer, 8 , n);
477
+ nwrite = fwrite (buffer, 8 , n, dfself->handle );
478
+ THFree (buffer);
479
+ }
480
+ }
481
+ else
482
+ {
483
+ long i;
484
+ for (i = 0 ; i < n; i++)
485
+ {
486
+ long res = 0 ;
487
+ int ret = fprintf (dfself->handle , " %ld" , res); data[i] = res; if (ret <= 0 ) break ; else nwrite++;
488
+ if ( dfself->file .isAutoSpacing && (i < n-1 ) )
489
+ fprintf (dfself->handle , " " );
490
+ }
491
+ if (dfself->file .isAutoSpacing && (n > 0 ))
492
+ fprintf (dfself->handle , " \n " );
493
+ }
494
+
495
+ if (nwrite != n)
496
+ {
497
+ dfself->file .hasError = 1 ;
498
+ if (!dfself->file .isQuiet )
499
+ THError (" write error: wrote %d blocks instead of %d" , nwrite, n);
500
+ }
501
+
502
+ return nwrite;
503
+ }
504
+
320
505
static long THDiskFile_readString (THFile *self, const char *format, char **str_)
321
506
{
322
507
THDiskFile *dfself = (THDiskFile*)(self);
@@ -494,6 +679,7 @@ THFile *THDiskFile_new(const char *name, const char *mode, int isQuiet)
494
679
self->name = (char *)THAlloc (strlen (name)+1 );
495
680
strcpy (self->name , name);
496
681
self->isNativeEncoding = 1 ;
682
+ self->longSize = 0 ;
497
683
498
684
self->file .vtable = &vtable;
499
685
self->file .isQuiet = isQuiet;
@@ -595,6 +781,7 @@ THFile *THPipeFile_new(const char *name, const char *mode, int isQuiet)
595
781
self->name = (char *)THAlloc (strlen (name)+1 );
596
782
strcpy (self->name , name);
597
783
self->isNativeEncoding = 1 ;
784
+ self->longSize = 0 ;
598
785
599
786
self->file .vtable = &vtable;
600
787
self->file .isQuiet = isQuiet;
0 commit comments