@@ -447,6 +447,33 @@ static inline void write_u16(std::ofstream& o, uint16_t v){ o.write(reinterpret_
447447static inline void write_f64 (std::ofstream& o, double v){ o.write (reinterpret_cast <const char *>(&v),8 ); }
448448static inline void write_u8 (std::ofstream& o, uint8_t v){ o.write (reinterpret_cast <const char *>(&v),1 ); }
449449
450+
451+ static inline bool read_u32 (std::ifstream& in, uint32_t & v){
452+ in.read (reinterpret_cast <char *>(&v), 4 );
453+ return (bool )in;
454+ }
455+ static inline bool read_i32 (std::ifstream& in, int32_t & v){
456+ in.read (reinterpret_cast <char *>(&v), 4 );
457+ return (bool )in;
458+ }
459+ static inline bool read_u64 (std::ifstream& in, uint64_t & v){
460+ in.read (reinterpret_cast <char *>(&v), 8 );
461+ return (bool )in;
462+ }
463+ static inline bool read_u16 (std::ifstream& in, uint16_t & v){
464+ in.read (reinterpret_cast <char *>(&v), 2 );
465+ return (bool )in;
466+ }
467+ static inline bool read_f64 (std::ifstream& in, double & v){
468+ in.read (reinterpret_cast <char *>(&v), 8 );
469+ return (bool )in;
470+ }
471+ static inline bool read_u8 (std::ifstream& in, uint8_t & v){
472+ in.read (reinterpret_cast <char *>(&v), 1 );
473+ return (bool )in;
474+ }
475+
476+
450477static inline bool read_text_file (const std::string& path, std::string& out){
451478 std::ifstream f (path);
452479 if (!f) return false ;
@@ -562,7 +589,7 @@ static inline bool write_prime95_s1_from_bytes(const std::string& outPath, uint3
562589 #elif defined(__arm__) || defined(_M_ARM)
563590 arch_str = " ARM" ;
564591 #else
565- arch_str = " unknown " ;
592+ arch_str = " " ;
566593 #endif
567594
568595 std::string json = std::string (" {\" programs\" :[{\" work\" :{\" type\" :\" PM1\" ,\" stage\" :\" 1\" },\" program\" :{\" name\" :\" prmers\" ,\" version\" :\" " + core::PRMERS_VERSION + " \" },\" os\" :{\" os\" :\" " ) + os_str + " \" ,\" architecture\" :\" " + arch_str + " \" },\" date_start\" :\" " + ds + " \" ,\" date_end\" :\" " + de + " \" }]}" ;
@@ -595,6 +622,83 @@ static inline bool write_prime95_s1_from_bytes(const std::string& outPath, uint3
595622 return (bool )out;
596623}
597624
625+ static inline bool read_prime95_s1_to_bytes (const std::string& path,
626+ uint32_t & p_out,
627+ uint64_t & B1_out,
628+ std::vector<uint8_t >& data_out)
629+ {
630+ std::ifstream in (path, std::ios::binary);
631+ if (!in) {
632+ std::cerr << " Error: cannot open Prime95 S1 file " << path << " for reading\n " ;
633+ return false ;
634+ }
635+
636+ uint32_t magic = 0 ;
637+ uint32_t ver = 0 ;
638+ double fver = 0.0 ;
639+ int32_t type = 0 ;
640+ uint32_t p = 0 ;
641+ int32_t unused_n = 0 ;
642+ uint8_t stage0 = 0 , stage1 = 0 ;
643+ uint16_t reserved = 0 ;
644+ uint64_t zero = 0 ;
645+ double f1 = 0.0 ;
646+ uint32_t chk_file = 0 ;
647+ int32_t flag5 = 0 ;
648+ uint64_t B1_a = 0 ;
649+ uint64_t B1_b = 0 ;
650+ int32_t flag1 = 0 ;
651+ int32_t nWords = 0 ;
652+
653+ // Lire l’en-tête dans le même ordre que write_prime95_s1_from_bytes
654+ if (!read_u32 (in, magic)) return false ;
655+ if (!read_u32 (in, ver)) return false ;
656+ if (!read_f64 (in, fver)) return false ;
657+ if (!read_i32 (in, type)) return false ;
658+ if (!read_u32 (in, p)) return false ;
659+ if (!read_i32 (in, unused_n))return false ;
660+ if (!read_u8 (in, stage0)) return false ;
661+ if (!read_u8 (in, stage1)) return false ;
662+ if (!read_u16 (in, reserved))return false ;
663+ if (!read_u64 (in, zero)) return false ;
664+ if (!read_f64 (in, f1)) return false ;
665+ if (!read_u32 (in, chk_file))return false ;
666+ if (!read_i32 (in, flag5)) return false ;
667+ if (!read_u64 (in, B1_a)) return false ;
668+ if (!read_u64 (in, B1_b)) return false ;
669+ if (!read_i32 (in, flag1)) return false ;
670+ if (!read_i32 (in, nWords)) return false ;
671+
672+ if (nWords < 0 ) {
673+ std::cerr << " Error: negative word count in Prime95 S1 file " << path << " \n " ;
674+ return false ;
675+ }
676+
677+ size_t nBytes = static_cast <size_t >(nWords) * 4u ;
678+ data_out.assign (nBytes, 0 );
679+
680+ in.read (reinterpret_cast <char *>(data_out.data ()),
681+ static_cast <std::streamsize>(nBytes));
682+ if (!in) {
683+ std::cerr << " Error: truncated Prime95 S1 data in " << path << " \n " ;
684+ return false ;
685+ }
686+
687+ // Sorties
688+ p_out = p;
689+ B1_out = B1_a; // B1_a == B1_b dans ton writer
690+
691+ // Vérifier le checksum (même formule que lors de l’écriture)
692+ uint32_t chk_calc = checksum_prime95_s1 (B1_out, data_out);
693+ if (chk_calc != chk_file) {
694+ std::cerr << " Warning: checksum mismatch in Prime95 S1 file " << path
695+ << " (file=" << chk_file << " , computed=" << chk_calc << " )\n " ;
696+ // On continue quand même : les données sont probablement correctes.
697+ }
698+
699+ return true ;
700+ }
701+
598702
599703static inline mpz_class compute_X_with_dots (engine* eng, engine::Reg reg, const mpz_class& Mp) {
600704 using namespace std ::chrono;
0 commit comments