@@ -610,7 +610,9 @@ oct_data_conv::data_type_as_string (oct_data_conv::data_type dt)
610
610
{ \
611
611
OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
612
612
std::streamsize n_bytes = size * static_cast <std::streamsize> (len); \
613
- stream.read (reinterpret_cast <char *> (ptr), n_bytes); \
613
+ do_read (stream, reinterpret_cast <char *> (ptr), n_bytes); \
614
+ if (! stream) \
615
+ return ; \
614
616
if (swap) \
615
617
swap_bytes< size > (ptr, len); \
616
618
for (octave_idx_type i = 0 ; i < len; i++) \
@@ -633,7 +635,7 @@ oct_data_conv::data_type_as_string (oct_data_conv::data_type dt)
633
635
for (octave_idx_type i = 0 ; i < len; i++) \
634
636
ptr[i] = static_cast <TYPE> (data[i]); \
635
637
std::streamsize n_bytes = size * static_cast <std::streamsize> (len); \
636
- stream. write ( reinterpret_cast <char *> (ptr), n_bytes); \
638
+ do_write (stream, reinterpret_cast <const char *> (ptr), n_bytes); \
637
639
} \
638
640
} \
639
641
while (0 )
@@ -798,6 +800,22 @@ do_float_format_conversion (void *data, std::size_t sz, octave_idx_type len,
798
800
}
799
801
}
800
802
803
+ static void
804
+ do_read (std::istream& is, char *byte_data, std::streamsize n_bytes)
805
+ {
806
+ // read large data in chunks of 64 MiB
807
+ constexpr std::streamsize chunk_size = 64 * 1024 * 1024 ;
808
+ for (std::streamsize offset = 0 ; offset < n_bytes; )
809
+ {
810
+ std::streamsize to_read = std::min (chunk_size, n_bytes - offset);
811
+ is.read (byte_data + offset, to_read);
812
+
813
+ if (! is)
814
+ return ;
815
+
816
+ offset += to_read;
817
+ }
818
+ }
801
819
void
802
820
read_doubles (std::istream& is, double *data, save_type type,
803
821
octave_idx_type len, bool swap,
@@ -832,8 +850,10 @@ read_doubles (std::istream& is, double *data, save_type type,
832
850
case LS_FLOAT:
833
851
{
834
852
OCTAVE_LOCAL_BUFFER (float , ptr, len);
835
- std::streamsize n_bytes = 4 * static_cast <std::streamsize> (len);
836
- is.read (reinterpret_cast <char *> (ptr), n_bytes);
853
+ std::streamsize n_bytes = sizeof (float ) * static_cast <std::streamsize> (len);
854
+ do_read (is, reinterpret_cast <char *> (data), n_bytes);
855
+ if (! is)
856
+ return ;
837
857
do_float_format_conversion (ptr, len, fmt);
838
858
for (octave_idx_type i = 0 ; i < len; i++)
839
859
data[i] = ptr[i];
@@ -842,8 +862,10 @@ read_doubles (std::istream& is, double *data, save_type type,
842
862
843
863
case LS_DOUBLE: // No conversion necessary.
844
864
{
845
- std::streamsize n_bytes = 8 * static_cast <std::streamsize> (len);
846
- is.read (reinterpret_cast <char *> (data), n_bytes);
865
+ std::streamsize n_bytes = sizeof (double ) * static_cast <std::streamsize> (len);
866
+ do_read (is, reinterpret_cast <char *> (data), n_bytes);
867
+ if (! is)
868
+ return ;
847
869
do_double_format_conversion (data, len, fmt);
848
870
// FIXME: Potentially add conversion code for MIPS NA here, Bug #59830.
849
871
//
@@ -891,8 +913,10 @@ read_floats (std::istream& is, float *data, save_type type,
891
913
892
914
case LS_FLOAT: // No conversion necessary.
893
915
{
894
- std::streamsize n_bytes = 4 * static_cast <std::streamsize> (len);
895
- is.read (reinterpret_cast <char *> (data), n_bytes);
916
+ std::streamsize n_bytes = sizeof (float ) * static_cast <std::streamsize> (len);
917
+ do_read (is, reinterpret_cast <char *> (data), n_bytes);
918
+ if (! is)
919
+ return ;
896
920
do_float_format_conversion (data, len, fmt);
897
921
}
898
922
break ;
@@ -901,7 +925,9 @@ read_floats (std::istream& is, float *data, save_type type,
901
925
{
902
926
OCTAVE_LOCAL_BUFFER (double , ptr, len);
903
927
std::streamsize n_bytes = 8 * static_cast <std::streamsize> (len);
904
- is.read (reinterpret_cast <char *> (ptr), n_bytes);
928
+ do_read (is, reinterpret_cast <char *> (data), n_bytes);
929
+ if (! is)
930
+ return ;
905
931
do_double_format_conversion (ptr, len, fmt);
906
932
for (octave_idx_type i = 0 ; i < len; i++)
907
933
data[i] = ptr[i];
@@ -914,6 +940,22 @@ read_floats (std::istream& is, float *data, save_type type,
914
940
}
915
941
}
916
942
943
+ static void
944
+ do_write (std::ostream& os, const char *byte_data, std::streamsize n_bytes)
945
+ {
946
+ // write large data in chunks of 64 MiB
947
+ constexpr std::streamsize chunk_size = 64 * 1024 * 1024 ;
948
+ for (std::streamsize written = 0 ; written < n_bytes; )
949
+ {
950
+ std::streamsize remaining = n_bytes - written;
951
+ std::streamsize to_write = std::min (chunk_size, remaining);
952
+ os.write (byte_data + written, to_write);
953
+ if (! os)
954
+ return ;
955
+ written += to_write;
956
+ }
957
+ }
958
+
917
959
void
918
960
write_doubles (std::ostream& os, const double *data, save_type type,
919
961
octave_idx_type len)
@@ -952,8 +994,9 @@ write_doubles (std::ostream& os, const double *data, save_type type,
952
994
{
953
995
char tmp_type = static_cast <char > (type);
954
996
os.write (&tmp_type, 1 );
955
- std::streamsize n_bytes = 8 * static_cast <std::streamsize> (len);
956
- os.write (reinterpret_cast <const char *> (data), n_bytes);
997
+
998
+ std::streamsize n_bytes = sizeof (double ) * static_cast <std::streamsize> (len);
999
+ do_write (os, reinterpret_cast <const char *> (data), n_bytes);
957
1000
}
958
1001
break ;
959
1002
@@ -998,8 +1041,8 @@ write_floats (std::ostream& os, const float *data, save_type type,
998
1041
{
999
1042
char tmp_type = static_cast <char > (type);
1000
1043
os.write (&tmp_type, 1 );
1001
- std::streamsize n_bytes = 4 * static_cast <std::streamsize> (len);
1002
- os. write ( reinterpret_cast <const char *> (data), n_bytes);
1044
+ std::streamsize n_bytes = sizeof ( float ) * static_cast <std::streamsize> (len);
1045
+ do_write (os, reinterpret_cast <const char *> (data), n_bytes);
1003
1046
}
1004
1047
break ;
1005
1048
0 commit comments