2020#include < zlib.h>
2121
2222#include < algorithm>
23+ #include < bit>
2324#include < cassert>
2425#include < cstddef>
25- #include < cstdlib>
2626#include < cstring>
2727#include < ctime>
2828#include < new>
@@ -251,23 +251,6 @@ inline uint64_t chd_file::file_append(const void *source, uint32_t length, uint3
251251}
252252
253253
254- // -------------------------------------------------
255- // bits_for_value - return the number of bits
256- // necessary to represent all numbers 0..value
257- // -------------------------------------------------
258-
259- inline uint8_t chd_file::bits_for_value (uint64_t value) noexcept
260- {
261- uint8_t result = 0 ;
262- while (value != 0 )
263- {
264- value >>= 1 ;
265- result++;
266- }
267- return result;
268- }
269-
270-
271254
272255// **************************************************************************
273256// CHD FILE MANAGEMENT
@@ -919,10 +902,10 @@ std::error_condition chd_file::codec_process_hunk(uint32_t hunknum)
919902 case V34_MAP_ENTRY_TYPE_COMPRESSED :
920903 {
921904 uint32_t const blocklen = get_u16be (&rawmap[12 ]) | (uint32_t (rawmap[14 ]) << 16 );
922- std::error_condition err = file_read (blockoffs, & m_compressed[ 0 ] , blocklen);
905+ std::error_condition err = file_read (blockoffs, m_compressed. data () , blocklen);
923906 if (UNEXPECTED (err))
924907 return err;
925- m_decompressor[0 ]->process (& m_compressed[ 0 ] , blocklen);
908+ m_decompressor[0 ]->process (m_compressed. data () , blocklen);
926909 return std::error_condition ();
927910 }
928911
@@ -958,11 +941,11 @@ std::error_condition chd_file::codec_process_hunk(uint32_t hunknum)
958941 case COMPRESSION_TYPE_2 :
959942 case COMPRESSION_TYPE_3 :
960943 {
961- std::error_condition err = file_read (blockoffs, & m_compressed[ 0 ] , blocklen);
944+ std::error_condition err = file_read (blockoffs, m_compressed. data () , blocklen);
962945 if (UNEXPECTED (err))
963946 return err;
964947 auto &decompressor = *m_decompressor[rawmap[0 ]];
965- decompressor.process (& m_compressed[ 0 ] , blocklen);
948+ decompressor.process (m_compressed. data () , blocklen);
966949 return std::error_condition ();
967950 }
968951
@@ -1045,10 +1028,10 @@ std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
10451028 case V34_MAP_ENTRY_TYPE_COMPRESSED :
10461029 {
10471030 uint32_t const blocklen = get_u16be (&rawmap[12 ]) | (uint32_t (rawmap[14 ]) << 16 );
1048- std::error_condition err = file_read (blockoffs, & m_compressed[ 0 ] , blocklen);
1031+ std::error_condition err = file_read (blockoffs, m_compressed. data () , blocklen);
10491032 if (UNEXPECTED (err))
10501033 return err;
1051- m_decompressor[0 ]->decompress (& m_compressed[ 0 ] , blocklen, dest, m_hunkbytes);
1034+ m_decompressor[0 ]->decompress (m_compressed. data () , blocklen, dest, m_hunkbytes);
10521035 if (UNEXPECTED (!nocrc && (util::crc32_creator::simple (dest, m_hunkbytes) != blockcrc)))
10531036 return std::error_condition (error::DECOMPRESSION_ERROR );
10541037 return std::error_condition ();
@@ -1115,14 +1098,14 @@ std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
11151098 case COMPRESSION_TYPE_2 :
11161099 case COMPRESSION_TYPE_3 :
11171100 {
1118- std::error_condition err = file_read (blockoffs, & m_compressed[ 0 ] , blocklen);
1101+ std::error_condition err = file_read (blockoffs, m_compressed. data () , blocklen);
11191102 if (UNEXPECTED (err))
11201103 return err;
11211104 auto &decompressor = *m_decompressor[rawmap[0 ]];
1122- decompressor.decompress (& m_compressed[ 0 ] , blocklen, dest, m_hunkbytes);
1105+ decompressor.decompress (m_compressed. data () , blocklen, dest, m_hunkbytes);
11231106 util::crc16_t const calculated = !decompressor.lossy ()
11241107 ? util::crc16_creator::simple (dest, m_hunkbytes)
1125- : util::crc16_creator::simple (& m_compressed[ 0 ] , blocklen);
1108+ : util::crc16_creator::simple (m_compressed. data () , blocklen);
11261109 if (UNEXPECTED (calculated != blockcrc))
11271110 return std::error_condition (error::DECOMPRESSION_ERROR );
11281111 return std::error_condition ();
@@ -1240,8 +1223,8 @@ std::error_condition chd_file::write_hunk(uint32_t hunknum, const void *buffer)
12401223 return err;
12411224
12421225 // update the cached hunk if we just wrote it
1243- if (hunknum == m_cachehunk && buffer != & m_cache[ 0 ] )
1244- memcpy (& m_cache[ 0 ] , buffer, m_hunkbytes);
1226+ if (hunknum == m_cachehunk && buffer != m_cache. data () )
1227+ memcpy (m_cache. data () , buffer, m_hunkbytes);
12451228
12461229 return std::error_condition ();
12471230 }
@@ -1329,7 +1312,7 @@ std::error_condition chd_file::read_bytes(uint64_t offset, void *buffer, uint32_
13291312 // otherwise, read from the cache
13301313 if (curhunk != m_cachehunk)
13311314 {
1332- std::error_condition err = read_hunk (curhunk, & m_cache[ 0 ] );
1315+ std::error_condition err = read_hunk (curhunk, m_cache. data () );
13331316 if (UNEXPECTED (err))
13341317 return err;
13351318 m_cachehunk = curhunk;
@@ -1381,13 +1364,13 @@ std::error_condition chd_file::write_bytes(uint64_t offset, const void *buffer,
13811364 // otherwise, write from the cache
13821365 if (curhunk != m_cachehunk)
13831366 {
1384- err = read_hunk (curhunk, & m_cache[ 0 ] );
1367+ err = read_hunk (curhunk, m_cache. data () );
13851368 if (UNEXPECTED (err))
13861369 return err;
13871370 m_cachehunk = curhunk;
13881371 }
13891372 memcpy (&m_cache[startoffs], source, endoffs + 1 - startoffs);
1390- err = write_hunk (curhunk, & m_cache[ 0 ] );
1373+ err = write_hunk (curhunk, m_cache. data () );
13911374 }
13921375
13931376 // handle errors and advance
@@ -1425,7 +1408,7 @@ std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_
14251408 // read the metadata
14261409 try { output.assign (metaentry.length , ' \0 ' ); }
14271410 catch (std::bad_alloc const &) { return std::errc::not_enough_memory; }
1428- return file_read (metaentry.offset + METADATA_HEADER_SIZE , & output[ 0 ] , metaentry.length );
1411+ return file_read (metaentry.offset + METADATA_HEADER_SIZE , output. data () , metaentry.length );
14291412}
14301413
14311414/* *
@@ -1453,7 +1436,7 @@ std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_
14531436 // read the metadata
14541437 try { output.resize (metaentry.length ); }
14551438 catch (std::bad_alloc const &) { return std::errc::not_enough_memory; }
1456- return file_read (metaentry.offset + METADATA_HEADER_SIZE , & output[ 0 ] , metaentry.length );
1439+ return file_read (metaentry.offset + METADATA_HEADER_SIZE , output. data () , metaentry.length );
14571440}
14581441
14591442/* *
@@ -1515,7 +1498,7 @@ std::error_condition chd_file::read_metadata(chd_metadata_tag searchtag, uint32_
15151498 // read the metadata
15161499 try { output.resize (metaentry.length ); }
15171500 catch (std::bad_alloc const &) { return std::errc::not_enough_memory; }
1518- err = file_read (metaentry.offset + METADATA_HEADER_SIZE , & output[ 0 ] , metaentry.length );
1501+ err = file_read (metaentry.offset + METADATA_HEADER_SIZE , output. data () , metaentry.length );
15191502 if (UNEXPECTED (err))
15201503 return err;
15211504 resulttag = metaentry.metatag ;
@@ -1678,12 +1661,12 @@ std::error_condition chd_file::clone_all_metadata(chd_file &source)
16781661 // read the metadata item
16791662 try { filedata.resize (metaentry.length ); }
16801663 catch (std::bad_alloc const &) { return std::errc::not_enough_memory; }
1681- err = source.file_read (metaentry.offset + METADATA_HEADER_SIZE , & filedata[ 0 ] , metaentry.length );
1664+ err = source.file_read (metaentry.offset + METADATA_HEADER_SIZE , filedata. data () , metaentry.length );
16821665 if (UNEXPECTED (err))
16831666 return err;
16841667
16851668 // write it to the destination
1686- err = write_metadata (metaentry.metatag , (uint32_t )-1 , & filedata[ 0 ] , metaentry.length , metaentry.flags );
1669+ err = write_metadata (metaentry.metatag , (uint32_t )-1 , filedata. data () , metaentry.length , metaentry.flags );
16871670 if (UNEXPECTED (err))
16881671 return err;
16891672 }
@@ -1725,28 +1708,34 @@ util::sha1_t chd_file::compute_overall_sha1(util::sha1_t rawsha1)
17251708
17261709 // allocate memory and read the data
17271710 filedata.resize (metaentry.length );
1728- err = file_read (metaentry.offset + METADATA_HEADER_SIZE , & filedata[ 0 ] , metaentry.length );
1711+ err = file_read (metaentry.offset + METADATA_HEADER_SIZE , filedata. data () , metaentry.length );
17291712 if (UNEXPECTED (err))
17301713 throw err;
17311714
17321715 // create an entry for this metadata and add it
17331716 metadata_hash hashentry;
17341717 put_u32be (hashentry.tag , metaentry.metatag );
1735- hashentry.sha1 = util::sha1_creator::simple (& filedata[ 0 ] , metaentry.length );
1718+ hashentry.sha1 = util::sha1_creator::simple (filedata. data () , metaentry.length );
17361719 hasharray.push_back (hashentry);
17371720 }
17381721 if (err != error::METADATA_NOT_FOUND )
17391722 throw err;
17401723
17411724 // sort the array
17421725 if (!hasharray.empty ())
1743- qsort (&hasharray[0 ], hasharray.size (), sizeof (hasharray[0 ]), metadata_hash_compare);
1726+ std::sort (
1727+ hasharray.begin (),
1728+ hasharray.end (),
1729+ [] (metadata_hash const &a, metadata_hash const &b)
1730+ {
1731+ return memcmp (&a, &b, sizeof (metadata_hash)) < 0 ;
1732+ });
17441733
17451734 // read the raw data hash from our header and start a new SHA1 with that data
17461735 util::sha1_creator overall_sha1;
17471736 overall_sha1.append (&rawsha1, sizeof (rawsha1));
17481737 if (!hasharray.empty ())
1749- overall_sha1.append (& hasharray[ 0 ] , hasharray.size () * sizeof (hasharray[0 ]));
1738+ overall_sha1.append (hasharray. data () , hasharray.size () * sizeof (hasharray[0 ]));
17501739 return overall_sha1.finish ();
17511740}
17521741
@@ -2073,11 +2062,11 @@ std::error_condition chd_file::compress_v5_map()
20732062 try
20742063 {
20752064 // first get a CRC-16 of the original rawmap
2076- util::crc16_t mapcrc = util::crc16_creator::simple (& m_rawmap[ 0 ] , m_hunkcount * 12 );
2065+ util::crc16_t mapcrc = util::crc16_creator::simple (m_rawmap. data () , m_hunkcount * 12 );
20772066
20782067 // create a buffer to hold the RLE data
20792068 std::vector<uint8_t > compression_rle (m_hunkcount);
2080- uint8_t *dest = & compression_rle[ 0 ] ;
2069+ uint8_t *dest = compression_rle. data () ;
20812070
20822071 // use a huffman encoder for 16 different codes, maximum length is 8 bits
20832072 huffman_encoder<16 , 8 > encoder;
@@ -2158,9 +2147,9 @@ std::error_condition chd_file::compress_v5_map()
21582147 }
21592148
21602149 // determine the number of bits we need to hold the a length and a hunk index
2161- const uint8_t lengthbits = bits_for_value (max_complen);
2162- const uint8_t selfbits = bits_for_value (max_self);
2163- const uint8_t parentbits = bits_for_value (max_parent);
2150+ const uint8_t lengthbits = std::bit_width (max_complen);
2151+ const uint8_t selfbits = std::bit_width (max_self);
2152+ const uint8_t parentbits = std::bit_width (max_parent);
21642153
21652154 // determine the needed size of the output buffer
21662155 // 16 bytes is required for the header
@@ -2185,13 +2174,13 @@ std::error_condition chd_file::compress_v5_map()
21852174 throw std::error_condition (error::COMPRESSION_ERROR );
21862175
21872176 // encode the data
2188- for (uint8_t *src = & compression_rle[ 0 ] ; src < dest; src++)
2177+ for (uint8_t *src = compression_rle. data () ; src < dest; src++)
21892178 encoder.encode_one (bitbuf, *src);
21902179
21912180 // for each compression type, output the relevant data
21922181 lastcomp = 0 ;
21932182 count = 0 ;
2194- uint8_t *src = & compression_rle[ 0 ] ;
2183+ uint8_t *src = compression_rle. data () ;
21952184 uint64_t firstoffs = 0 ;
21962185 for (uint32_t hunknum = 0 ; hunknum < m_hunkcount; hunknum++)
21972186 {
@@ -2256,7 +2245,7 @@ std::error_condition chd_file::compress_v5_map()
22562245 // write the map header
22572246 uint32_t complen = bitbuf.flush ();
22582247 assert (!bitbuf.overflow ());
2259- put_u32be (& compressed[ 0 ] , complen);
2248+ put_u32be (compressed. data () , complen);
22602249 put_u48be (&compressed[4 ], firstoffs);
22612250 put_u16be (&compressed[10 ], mapcrc);
22622251 compressed[12 ] = lengthbits;
@@ -2265,7 +2254,7 @@ std::error_condition chd_file::compress_v5_map()
22652254 compressed[15 ] = 0 ;
22662255
22672256 // write the result
2268- m_mapoffset = file_append (& compressed[ 0 ] , complen + 16 );
2257+ m_mapoffset = file_append (compressed. data () , complen + 16 );
22692258
22702259 // then write the map offset
22712260 uint8_t rawbuf[sizeof (uint64_t )];
@@ -2298,7 +2287,7 @@ void chd_file::decompress_v5_map()
22982287 // if no offset, we haven't written it yet
22992288 if (m_mapoffset == 0 )
23002289 {
2301- memset (& m_rawmap[ 0 ] , 0xff , m_rawmap.size ());
2290+ memset (m_rawmap. data () , 0xff , m_rawmap.size ());
23022291 return ;
23032292 }
23042293
@@ -2317,10 +2306,10 @@ void chd_file::decompress_v5_map()
23172306
23182307 // now read the map
23192308 std::vector<uint8_t > compressed (mapbytes);
2320- ioerr = file_read (m_mapoffset + 16 , & compressed[ 0 ] , mapbytes);
2309+ ioerr = file_read (m_mapoffset + 16 , compressed. data () , mapbytes);
23212310 if (UNEXPECTED (ioerr))
23222311 throw ioerr;
2323- bitstream_in bitbuf (& compressed[ 0 ] , compressed.size ());
2312+ bitstream_in bitbuf (compressed. data () , compressed.size ());
23242313
23252314 // first decode the compression types
23262315 huffman_decoder<16 , 8 > decoder;
@@ -2409,7 +2398,7 @@ void chd_file::decompress_v5_map()
24092398 }
24102399
24112400 // verify the final CRC
2412- if (UNEXPECTED (util::crc16_creator::simple (& m_rawmap[ 0 ] , m_hunkcount * 12 ) != mapcrc))
2401+ if (UNEXPECTED (util::crc16_creator::simple (m_rawmap. data () , m_hunkcount * 12 ) != mapcrc))
24132402 throw std::error_condition (error::DECOMPRESSION_ERROR );
24142403}
24152404
@@ -2643,7 +2632,7 @@ void chd_file::create_open_common()
26432632 }
26442633 else
26452634 {
2646- std::error_condition err = file_read (m_mapoffset, & m_rawmap[ 0 ] , m_rawmap.size ());
2635+ std::error_condition err = file_read (m_mapoffset, m_rawmap. data () , m_rawmap.size ());
26472636 if (UNEXPECTED (err))
26482637 throw err;
26492638 }
@@ -2906,23 +2895,6 @@ void chd_file::metadata_update_hash()
29062895 throw err;
29072896}
29082897
2909- /* *
2910- * @fn int CLIB_DECL chd_file::metadata_hash_compare(const void *elem1, const void *elem2)
2911- *
2912- * @brief -------------------------------------------------
2913- * metadata_hash_compare - compare two hash entries
2914- * -------------------------------------------------.
2915- *
2916- * @param elem1 The first element.
2917- * @param elem2 The second element.
2918- *
2919- * @return A CLIB_DECL.
2920- */
2921-
2922- int CLIB_DECL chd_file::metadata_hash_compare (const void *elem1, const void *elem2)
2923- {
2924- return memcmp (elem1, elem2, sizeof (metadata_hash));
2925- }
29262898
29272899
29282900
@@ -3002,7 +2974,7 @@ void chd_file_compressor::compress_begin()
30022974
30032975 // reset work item state
30042976 m_work_buffer.resize (hunk_bytes () * (WORK_BUFFER_HUNKS + 1 ));
3005- memset (& m_work_buffer[ 0 ] , 0 , m_work_buffer.size ());
2977+ memset (m_work_buffer. data () , 0 , m_work_buffer.size ());
30062978 m_compressed_buffer.resize (hunk_bytes () * WORK_BUFFER_HUNKS );
30072979 for (int itemnum = 0 ; itemnum < WORK_BUFFER_HUNKS ; itemnum++)
30082980 {
@@ -3306,8 +3278,8 @@ void chd_file_compressor::async_read()
33063278 if ((m_read_done_offset + numbytes) > logical_bytes ())
33073279 numbytes = logical_bytes () - m_read_done_offset;
33083280
3309- uint8_t *const dest = & m_work_buffer[ 0 ] + (m_read_done_offset % work_buffer_bytes);
3310- assert ((& m_work_buffer[ 0 ] == dest) || (&m_work_buffer[work_buffer_bytes / 2 ] == dest));
3281+ uint8_t *const dest = m_work_buffer. data () + (m_read_done_offset % work_buffer_bytes);
3282+ assert ((m_work_buffer. data () == dest) || (&m_work_buffer[work_buffer_bytes / 2 ] == dest));
33113283 assert (!(m_read_done_offset % hunk_bytes ()));
33123284 uint64_t const end_offset = m_read_done_offset + numbytes;
33133285
0 commit comments