Skip to content

Commit 15d9f50

Browse files
authored
os: add x64 mode for struct and raw read/write (vlang#9512)
1 parent b40d06e commit 15d9f50

2 files changed

Lines changed: 113 additions & 28 deletions

File tree

vlib/os/file.c.v

Lines changed: 113 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ pub fn (mut f File) read_struct<T>(mut t T) ? {
448448
}
449449

450450
// read_struct_at reads a single struct of type `T` at position specified in file
451-
pub fn (mut f File) read_struct_at<T>(mut t T, pos int) ? {
451+
pub fn (mut f File) read_struct_at<T>(mut t T, pos u64) ? {
452452
if !f.is_opened {
453453
return none
454454
}
@@ -457,9 +457,23 @@ pub fn (mut f File) read_struct_at<T>(mut t T, pos int) ? {
457457
return none
458458
}
459459
C.errno = 0
460-
C.fseek(f.cfile, pos, C.SEEK_SET)
461-
nbytes := int(C.fread(t, 1, tsize, f.cfile))
462-
C.fseek(f.cfile, 0, C.SEEK_END)
460+
mut nbytes := 0
461+
$if x64 {
462+
$if windows {
463+
C._fseeki64(f.cfile, pos, C.SEEK_SET)
464+
nbytes = int(C.fread(t, 1, tsize, f.cfile))
465+
C._fseeki64(f.cfile, 0, C.SEEK_END)
466+
} $else {
467+
C.fseeko(f.cfile, pos, C.SEEK_SET)
468+
nbytes = int(C.fread(t, 1, tsize, f.cfile))
469+
C.fseeko(f.cfile, 0, C.SEEK_END)
470+
}
471+
}
472+
$if x32 {
473+
C.fseek(f.cfile, pos, C.SEEK_SET)
474+
nbytes = int(C.fread(t, 1, tsize, f.cfile))
475+
C.fseek(f.cfile, 0, C.SEEK_END)
476+
}
463477
if C.errno != 0 {
464478
return error(posix_get_error_msg(C.errno))
465479
}
@@ -490,7 +504,7 @@ pub fn (mut f File) read_raw<T>() ?T {
490504
}
491505

492506
// read_raw_at reads and returns a single instance of type `T` starting at file byte offset `pos`
493-
pub fn (mut f File) read_raw_at<T>(pos int) ?T {
507+
pub fn (mut f File) read_raw_at<T>(pos u64) ?T {
494508
if !f.is_opened {
495509
return none
496510
}
@@ -499,17 +513,46 @@ pub fn (mut f File) read_raw_at<T>(pos int) ?T {
499513
return none
500514
}
501515
C.errno = 0
502-
if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 {
503-
return error(posix_get_error_msg(C.errno))
504-
}
516+
mut nbytes := 0
505517
mut t := T{}
506-
nbytes := int(C.fread(&t, 1, tsize, f.cfile))
507-
if C.errno != 0 {
508-
return error(posix_get_error_msg(C.errno))
518+
$if x64 {
519+
$if windows {
520+
if C._fseeki64(f.cfile, pos, C.SEEK_SET) != 0 {
521+
return error(posix_get_error_msg(C.errno))
522+
}
523+
nbytes = int(C.fread(&t, 1, tsize, f.cfile))
524+
if C.errno != 0 {
525+
return error(posix_get_error_msg(C.errno))
526+
}
527+
if C._fseeki64(f.cfile, 0, C.SEEK_END) != 0 {
528+
return error(posix_get_error_msg(C.errno))
529+
}
530+
} $else {
531+
if C.fseeko(f.cfile, pos, C.SEEK_SET) != 0 {
532+
return error(posix_get_error_msg(C.errno))
533+
}
534+
nbytes = int(C.fread(&t, 1, tsize, f.cfile))
535+
if C.errno != 0 {
536+
return error(posix_get_error_msg(C.errno))
537+
}
538+
if C.fseeko(f.cfile, 0, C.SEEK_END) != 0 {
539+
return error(posix_get_error_msg(C.errno))
540+
}
541+
}
509542
}
510-
if C.fseek(f.cfile, 0, C.SEEK_END) != 0 {
511-
return error(posix_get_error_msg(C.errno))
543+
$if x32 {
544+
if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 {
545+
return error(posix_get_error_msg(C.errno))
546+
}
547+
nbytes = int(C.fread(&t, 1, tsize, f.cfile))
548+
if C.errno != 0 {
549+
return error(posix_get_error_msg(C.errno))
550+
}
551+
if C.fseek(f.cfile, 0, C.SEEK_END) != 0 {
552+
return error(posix_get_error_msg(C.errno))
553+
}
512554
}
555+
513556
if nbytes != tsize {
514557
return error_with_code('incomplete struct read', nbytes)
515558
}
@@ -536,7 +579,7 @@ pub fn (mut f File) write_struct<T>(t &T) ? {
536579
}
537580

538581
// write_struct_at writes a single struct of type `T` at position specified in file
539-
pub fn (mut f File) write_struct_at<T>(t &T, pos int) ? {
582+
pub fn (mut f File) write_struct_at<T>(t &T, pos u64) ? {
540583
if !f.is_opened {
541584
return error('file is not opened')
542585
}
@@ -545,9 +588,23 @@ pub fn (mut f File) write_struct_at<T>(t &T, pos int) ? {
545588
return error('struct size is 0')
546589
}
547590
C.errno = 0
548-
C.fseek(f.cfile, pos, C.SEEK_SET)
549-
nbytes := int(C.fwrite(t, 1, tsize, f.cfile))
550-
C.fseek(f.cfile, 0, C.SEEK_END)
591+
mut nbytes := 0
592+
$if x64 {
593+
$if windows {
594+
C._fseeki64(f.cfile, pos, C.SEEK_SET)
595+
nbytes = int(C.fwrite(t, 1, tsize, f.cfile))
596+
C._fseeki64(f.cfile, 0, C.SEEK_END)
597+
} $else {
598+
C.fseeko(f.cfile, pos, C.SEEK_SET)
599+
nbytes = int(C.fwrite(t, 1, tsize, f.cfile))
600+
C.fseeko(f.cfile, 0, C.SEEK_END)
601+
}
602+
}
603+
$if x32 {
604+
C.fseek(f.cfile, pos, C.SEEK_SET)
605+
nbytes = int(C.fwrite(t, 1, tsize, f.cfile))
606+
C.fseek(f.cfile, 0, C.SEEK_END)
607+
}
551608
if C.errno != 0 {
552609
return error(posix_get_error_msg(C.errno))
553610
}
@@ -578,24 +635,54 @@ pub fn (mut f File) write_raw<T>(t &T) ? {
578635
}
579636

580637
// write_raw_at writes a single instance of type `T` starting at file byte offset `pos`
581-
pub fn (mut f File) write_raw_at<T>(t &T, pos int) ? {
638+
pub fn (mut f File) write_raw_at<T>(t &T, pos u64) ? {
582639
if !f.is_opened {
583640
return error('file is not opened')
584641
}
585642
tsize := int(sizeof(T))
586643
if tsize == 0 {
587644
return error('struct size is 0')
588645
}
589-
if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 {
590-
return error(posix_get_error_msg(C.errno))
591-
}
592-
nbytes := int(C.fwrite(t, 1, tsize, f.cfile))
593-
if C.errno != 0 {
594-
return error(posix_get_error_msg(C.errno))
646+
mut nbytes := 0
647+
648+
$if x64 {
649+
$if windows {
650+
if C._fseeki64(f.cfile, pos, C.SEEK_SET) != 0 {
651+
return error(posix_get_error_msg(C.errno))
652+
}
653+
nbytes = int(C.fwrite(t, 1, tsize, f.cfile))
654+
if C.errno != 0 {
655+
return error(posix_get_error_msg(C.errno))
656+
}
657+
if C._fseeki64(f.cfile, 0, C.SEEK_END) != 0 {
658+
return error(posix_get_error_msg(C.errno))
659+
}
660+
} $else {
661+
if C.fseeko(f.cfile, pos, C.SEEK_SET) != 0 {
662+
return error(posix_get_error_msg(C.errno))
663+
}
664+
nbytes = int(C.fwrite(t, 1, tsize, f.cfile))
665+
if C.errno != 0 {
666+
return error(posix_get_error_msg(C.errno))
667+
}
668+
if C.fseeko(f.cfile, 0, C.SEEK_END) != 0 {
669+
return error(posix_get_error_msg(C.errno))
670+
}
671+
}
595672
}
596-
if C.fseek(f.cfile, 0, C.SEEK_END) != 0 {
597-
return error(posix_get_error_msg(C.errno))
673+
$if x32 {
674+
if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 {
675+
return error(posix_get_error_msg(C.errno))
676+
}
677+
nbytes = int(C.fwrite(t, 1, tsize, f.cfile))
678+
if C.errno != 0 {
679+
return error(posix_get_error_msg(C.errno))
680+
}
681+
if C.fseek(f.cfile, 0, C.SEEK_END) != 0 {
682+
return error(posix_get_error_msg(C.errno))
683+
}
598684
}
685+
599686
if nbytes != tsize {
600687
return error_with_code('incomplete struct write', nbytes)
601688
}

vlib/os/os_c.v

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ fn C.CopyFile(&u32, &u32, int) int
2525

2626
fn C.execvp(file charptr, argv &charptr) int
2727

28-
// fn C.lstat(charptr, voidptr) u64
29-
3028
fn C._wstat64(charptr, voidptr) u64
3129

3230
// fn C.proc_pidpath(int, byteptr, int) int

0 commit comments

Comments
 (0)