Commit 4fa7b1eb606ecd749409a907ea7a47b39d48cb7b

Authored by Jay Berkenbilt
1 parent cd2bd667

Add remove_file and rename_file to QUtil

ChangeLog
  1 +2019-08-31 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add methods rename_file and remove_file to QUtil.
  4 +
1 5 2019-08-24 Jay Berkenbilt <ejb@ql.org>
2 6  
3 7 * Add QPDF::userPasswordMatched() and QPDF::ownerPasswordMatched()
... ...
include/qpdf/QUtil.hh
... ... @@ -111,6 +111,13 @@ namespace QUtil
111 111 bool same_file(char const* name1, char const* name2);
112 112  
113 113 QPDF_DLL
  114 + void remove_file(char const* path);
  115 +
  116 + // rename_file will overwrite newname if it exists
  117 + QPDF_DLL
  118 + void rename_file(char const* oldname, char const* newname);
  119 +
  120 + QPDF_DLL
114 121 char* copy_string(std::string const&);
115 122  
116 123 // Returns lower-case hex-encoded version of the string, treating
... ...
libqpdf/QUtil.cc
... ... @@ -394,15 +394,14 @@ QUtil::os_wrapper(std::string const&amp; description, int status)
394 394 return status;
395 395 }
396 396  
397   -FILE*
398   -QUtil::safe_fopen(char const* filename, char const* mode)
399   -{
400   - FILE* f = 0;
401 397 #ifdef _WIN32
  398 +static PointerHolder<wchar_t>
  399 +win_convert_filename(char const* filename)
  400 +{
402 401 // Convert the utf-8 encoded filename argument to wchar_t*. First,
403 402 // convert to utf16, then to wchar_t*. Note that u16 will start
404 403 // with the UTF16 marker, which we skip.
405   - std::string u16 = utf8_to_utf16(filename);
  404 + std::string u16 = QUtil::utf8_to_utf16(filename);
406 405 size_t len = u16.length();
407 406 size_t wlen = (len / 2) - 1;
408 407 PointerHolder<wchar_t> wfilenamep(true, new wchar_t[wlen + 1]);
... ... @@ -415,6 +414,17 @@ QUtil::safe_fopen(char const* filename, char const* mode)
415 414 (static_cast<unsigned char>(u16.at(i)) << 8) +
416 415 static_cast<unsigned char>(u16.at(i+1)));
417 416 }
  417 + return wfilenamep;
  418 +}
  419 +#endif
  420 +
  421 +FILE*
  422 +QUtil::safe_fopen(char const* filename, char const* mode)
  423 +{
  424 + FILE* f = 0;
  425 +#ifdef _WIN32
  426 + PointerHolder<wchar_t> wfilenamep = win_convert_filename(filename);
  427 + wchar_t* wfilename = wfilenamep.getPointer();
418 428 PointerHolder<wchar_t> wmodep(true, new wchar_t[strlen(mode) + 1]);
419 429 wchar_t* wmode = wmodep.getPointer();
420 430 wmode[strlen(mode)] = 0;
... ... @@ -537,6 +547,40 @@ QUtil::same_file(char const* name1, char const* name2)
537 547 return false;
538 548 }
539 549  
  550 +
  551 +void
  552 +QUtil::remove_file(char const* path)
  553 +{
  554 +#ifdef _WIN32
  555 + PointerHolder<wchar_t> wpath = win_convert_filename(path);
  556 + os_wrapper(std::string("remove ") + path, _wunlink(wpath.getPointer()));
  557 +#else
  558 + os_wrapper(std::string("remove ") + path, unlink(path));
  559 +#endif
  560 +}
  561 +
  562 +void
  563 +QUtil::rename_file(char const* oldname, char const* newname)
  564 +{
  565 +#ifdef _WIN32
  566 + try
  567 + {
  568 + remove_file(newname);
  569 + }
  570 + catch (QPDFSystemError&)
  571 + {
  572 + // ignore
  573 + }
  574 + PointerHolder<wchar_t> wold = win_convert_filename(oldname);
  575 + PointerHolder<wchar_t> wnew = win_convert_filename(newname);
  576 + os_wrapper(std::string("rename ") + oldname + " " + newname,
  577 + _wrename(wold.getPointer(), wnew.getPointer()));
  578 +#else
  579 + os_wrapper(std::string("rename ") + oldname + " " + newname,
  580 + rename(oldname, newname));
  581 +#endif
  582 +}
  583 +
540 584 char*
541 585 QUtil::copy_string(std::string const& str)
542 586 {
... ...
libtests/qtest/qutil/qutil.out
... ... @@ -99,3 +99,9 @@ read 24652 bytes
99 99 ---- hex encode/decode
100 100 begin hex encode/decode
101 101 end hex encode/decode
  102 +---- rename/delete
  103 +create file
  104 +rename file
  105 +create file
  106 +rename over existing
  107 +delete file
... ...
libtests/qutil.cc
... ... @@ -457,6 +457,57 @@ void hex_encode_decode_test()
457 457 std::cout << "end hex encode/decode\n";
458 458 }
459 459  
  460 +static void assert_no_file(char const* filename)
  461 +{
  462 + try
  463 + {
  464 + fclose(QUtil::safe_fopen(filename, "r"));
  465 + assert(false);
  466 + }
  467 + catch (QPDFSystemError&)
  468 + {
  469 + }
  470 +}
  471 +
  472 +void rename_delete_test()
  473 +{
  474 + PointerHolder<char> buf;
  475 + size_t size = 0;
  476 +
  477 + try
  478 + {
  479 + QUtil::remove_file("old\xcf\x80");
  480 + }
  481 + catch (QPDFSystemError&)
  482 + {
  483 + }
  484 + assert_no_file("old\xcf\x80");
  485 + std::cout << "create file" << std::endl;;
  486 + FILE* f1 = QUtil::safe_fopen("old\xcf\x80", "w");
  487 + fprintf(f1, "one");
  488 + fclose(f1);
  489 + QUtil::read_file_into_memory("old\xcf\x80", buf, size);
  490 + assert(memcmp(buf.getPointer(), "one", 3) == 0);
  491 + std::cout << "rename file" << std::endl;;
  492 + QUtil::rename_file("old\xcf\x80", "old\xcf\x80.~tmp");
  493 + QUtil::read_file_into_memory("old\xcf\x80.~tmp", buf, size);
  494 + assert(memcmp(buf.getPointer(), "one", 3) == 0);
  495 + assert_no_file("old\xcf\x80");
  496 + std::cout << "create file" << std::endl;;
  497 + f1 = QUtil::safe_fopen("old\xcf\x80", "w");
  498 + fprintf(f1, "two");
  499 + fclose(f1);
  500 + std::cout << "rename over existing" << std::endl;;
  501 + QUtil::rename_file("old\xcf\x80", "old\xcf\x80.~tmp");
  502 + QUtil::read_file_into_memory("old\xcf\x80.~tmp", buf, size);
  503 + assert(memcmp(buf.getPointer(), "two", 3) == 0);
  504 + assert_no_file("old\xcf\x80");
  505 + std::cout << "delete file" << std::endl;;
  506 + QUtil::remove_file("old\xcf\x80.~tmp");
  507 + assert_no_file("old\xcf\x80");
  508 + assert_no_file("old\xcf\x80.~tmp");
  509 +}
  510 +
460 511 int main(int argc, char* argv[])
461 512 {
462 513 try
... ... @@ -485,6 +536,8 @@ int main(int argc, char* argv[])
485 536 read_from_file_test();
486 537 std::cout << "---- hex encode/decode" << std::endl;
487 538 hex_encode_decode_test();
  539 + std::cout << "---- rename/delete" << std::endl;
  540 + rename_delete_test();
488 541 }
489 542 catch (std::exception& e)
490 543 {
... ...