@@ -1240,6 +1240,7 @@ zip_file_t *zip_fopen_index(zip_t *za, zip_uint64_t index, zip_flags_t flags) {
12401240 }
12411241 zf -> data = buf ;
12421242 zf -> size = sz ;
1243+ zf -> pos = 0 ;
12431244 return zf ;
12441245}
12451246
@@ -1252,6 +1253,100 @@ int zip_fclose(zip_file_t *zf) {
12521253 return 0 ;
12531254}
12541255
1256+ zip_int64_t zip_fread (zip_file_t * zf , void * buf , zip_uint64_t nbytes ) {
1257+ if (!zf || !buf ) {
1258+ return -1 ;
1259+ }
1260+ if (zf -> pos >= zf -> size ) {
1261+ return 0 ;
1262+ }
1263+ zip_uint64_t remaining = zf -> size - zf -> pos ;
1264+ zip_uint64_t to_copy = (nbytes < remaining ) ? nbytes : remaining ;
1265+ memcpy (buf , (uint8_t * )zf -> data + zf -> pos , to_copy );
1266+ zf -> pos += to_copy ;
1267+ return (zip_int64_t )to_copy ;
1268+ }
1269+
1270+ void zip_stat_init (zip_stat_t * st ) {
1271+ if (!st ) {
1272+ return ;
1273+ }
1274+ st -> valid = 0 ;
1275+ st -> name = NULL ;
1276+ st -> index = ZIP_UINT64_MAX ;
1277+ st -> size = 0 ;
1278+ st -> comp_size = 0 ;
1279+ st -> mtime = (time_t )- 1 ;
1280+ st -> crc = 0 ;
1281+ st -> comp_method = ZIP_CM_STORE ;
1282+ }
1283+
1284+ int zip_stat_index (zip_t * za , zip_uint64_t index , zip_flags_t flags , zip_stat_t * st ) {
1285+ (void )flags ;
1286+ if (!za || !st || index >= za -> n_entries ) {
1287+ return -1 ;
1288+ }
1289+ zip_stat_init (st );
1290+ struct otezip_entry * e = & za -> entries [index ];
1291+ st -> name = e -> name ;
1292+ st -> index = index ;
1293+ st -> size = e -> uncomp_size ;
1294+ st -> comp_size = e -> comp_size ;
1295+ st -> crc = e -> crc32 ;
1296+ st -> comp_method = e -> method ;
1297+ st -> valid = ZIP_STAT_NAME | ZIP_STAT_INDEX | ZIP_STAT_SIZE | ZIP_STAT_COMP_SIZE | ZIP_STAT_CRC | ZIP_STAT_COMP_METHOD ;
1298+ return 0 ;
1299+ }
1300+
1301+ const char * zip_get_name (zip_t * za , zip_uint64_t index , zip_flags_t flags ) {
1302+ (void )flags ;
1303+ if (!za || index >= za -> n_entries ) {
1304+ return NULL ;
1305+ }
1306+ return za -> entries [index ].name ;
1307+ }
1308+
1309+ int zip_stat (zip_t * za , const char * fname , zip_flags_t flags , zip_stat_t * st ) {
1310+ zip_int64_t index = zip_name_locate (za , fname , flags );
1311+ if (index < 0 ) {
1312+ return -1 ;
1313+ }
1314+ return zip_stat_index (za , (zip_uint64_t )index , flags , st );
1315+ }
1316+
1317+ zip_t * zip_open_from_source (zip_source_t * src , int flags , zip_error_t * error ) {
1318+ (void )error ;
1319+ if (!src ) {
1320+ return NULL ;
1321+ }
1322+ /* Since otezip's zip_source_t is a simple buffer wrapper,
1323+ * we create a temporary file and write the buffer to it,
1324+ * then open the archive normally. */
1325+ char tmp_path [] = "/tmp/otezip_XXXXXX" ;
1326+ int fd = mkstemp (tmp_path );
1327+ if (fd < 0 ) {
1328+ return NULL ;
1329+ }
1330+ /* Write the source buffer to the temp file */
1331+ ssize_t written = write (fd , src -> buf , src -> len );
1332+ close (fd );
1333+ if (written != (ssize_t )src -> len ) {
1334+ unlink (tmp_path );
1335+ return NULL ;
1336+ }
1337+ /* Open the archive from the temp file */
1338+ int errorp = 0 ;
1339+ zip_t * za = zip_open (tmp_path , flags , & errorp );
1340+ if (!za ) {
1341+ unlink (tmp_path );
1342+ return NULL ;
1343+ }
1344+ /* Note: The temp file will be cleaned up when the archive is closed.
1345+ * This is a simple implementation; a more sophisticated one would
1346+ * handle in-memory sources directly. */
1347+ return za ;
1348+ }
1349+
12551350/* Helper function to write local file header */
12561351static uint32_t otezip_write_local_header (FILE * fp , const char * name , uint32_t comp_method ,
12571352 uint32_t comp_size , uint32_t uncomp_size , uint32_t crc32 ) {
@@ -1414,3 +1509,73 @@ zip_source_t *zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, i
14141509 src -> freep = freep ;
14151510 return src ;
14161511}
1512+
1513+ zip_source_t * zip_source_buffer_create (const void * data , zip_uint64_t len , int freep , zip_error_t * error ) {
1514+ (void )error ;
1515+ return zip_source_buffer (NULL , data , len , freep );
1516+ }
1517+
1518+ void zip_source_free (zip_source_t * src ) {
1519+ if (!src ) {
1520+ return ;
1521+ }
1522+ if (src -> freep && src -> buf ) {
1523+ free ((void * )src -> buf );
1524+ }
1525+ free (src );
1526+ }
1527+
1528+ /* Helper to replace entry data at an existing index */
1529+ static int otezip_replace_entry_data (zip_t * za , zip_uint64_t index , zip_source_t * src ) {
1530+ if (!za || index >= za -> n_entries || !src ) {
1531+ return -1 ;
1532+ }
1533+ if (za -> mode != 1 ) {
1534+ return -1 ;
1535+ }
1536+ struct otezip_entry * e = & za -> entries [index ];
1537+ /* Free old data if present */
1538+ free ((void * )src -> buf );
1539+ /* Update entry with new source data */
1540+ e -> uncomp_size = (uint32_t )src -> len ;
1541+ e -> crc32 = otezip_crc32 (0 , src -> buf , src -> len );
1542+ /* Compress the data using the selected method */
1543+ uint8_t * comp_buf = NULL ;
1544+ uint32_t comp_size = 0 ;
1545+ if (otezip_compress_data ((uint8_t * )src -> buf , src -> len , & comp_buf , & comp_size , & e -> method ) != 0 ) {
1546+ return -1 ;
1547+ }
1548+ if ((uint64_t )comp_size > MZIP_MAX_PAYLOAD ) {
1549+ free (comp_buf );
1550+ return -1 ;
1551+ }
1552+ e -> comp_size = comp_size ;
1553+ /* Write the updated entry */
1554+ long current_pos = ftell (za -> fp );
1555+ if (current_pos < 0 ) {
1556+ free (comp_buf );
1557+ return -1 ;
1558+ }
1559+ e -> local_hdr_ofs = (uint32_t )current_pos ;
1560+ otezip_write_local_header (za -> fp , e -> name , e -> method , e -> comp_size , e -> uncomp_size , e -> crc32 );
1561+ fwrite (comp_buf , 1 , comp_size , za -> fp );
1562+ free (comp_buf );
1563+ return 0 ;
1564+ }
1565+
1566+ int zip_file_replace (zip_t * za , zip_uint64_t index , zip_source_t * src , zip_flags_t flags ) {
1567+ (void )flags ;
1568+ if (otezip_replace_entry_data (za , index , src ) != 0 ) {
1569+ return -1 ;
1570+ }
1571+ return 0 ;
1572+ }
1573+
1574+ /* Deprecated functions - just forward to the new API */
1575+ int zip_replace (zip_t * za , zip_uint64_t index , zip_source_t * src ) {
1576+ return zip_file_replace (za , index , src , 0 );
1577+ }
1578+
1579+ zip_int64_t zip_add (zip_t * za , const char * name , zip_source_t * src ) {
1580+ return zip_file_add (za , name , src , 0 );
1581+ }
0 commit comments