The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
4.6KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "../jucer_Headers.h"
  19. #include "jucer_CodeHelpers.h"
  20. //==============================================================================
  21. namespace FileHelpers
  22. {
  23. int64 calculateMemoryHashCode (const void* data, const int numBytes)
  24. {
  25. int64 t = 0;
  26. for (int i = 0; i < numBytes; ++i)
  27. t = t * 65599 + static_cast <const uint8*> (data)[i];
  28. return t;
  29. }
  30. int64 calculateStreamHashCode (InputStream& in)
  31. {
  32. int64 t = 0;
  33. const int bufferSize = 4096;
  34. HeapBlock <uint8> buffer;
  35. buffer.malloc (bufferSize);
  36. for (;;)
  37. {
  38. const int num = in.read (buffer, bufferSize);
  39. if (num <= 0)
  40. break;
  41. for (int i = 0; i < num; ++i)
  42. t = t * 65599 + buffer[i];
  43. }
  44. return t;
  45. }
  46. int64 calculateFileHashCode (const File& file)
  47. {
  48. ScopedPointer <FileInputStream> stream (file.createInputStream());
  49. return stream != nullptr ? calculateStreamHashCode (*stream) : 0;
  50. }
  51. bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, int numBytes)
  52. {
  53. if (file.getSize() == numBytes
  54. && calculateMemoryHashCode (data, numBytes) == calculateFileHashCode (file))
  55. return true;
  56. if (file.exists())
  57. return file.replaceWithData (data, numBytes);
  58. else
  59. return file.appendData (data, numBytes);
  60. }
  61. bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData)
  62. {
  63. return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize());
  64. }
  65. bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData)
  66. {
  67. const char* const utf8 = newData.toUTF8();
  68. return overwriteFileWithNewDataIfDifferent (file, utf8, strlen (utf8));
  69. }
  70. bool containsAnyNonHiddenFiles (const File& folder)
  71. {
  72. DirectoryIterator di (folder, false);
  73. while (di.next())
  74. if (! di.getFile().isHidden())
  75. return true;
  76. return false;
  77. }
  78. String unixStylePath (const String& path)
  79. {
  80. return path.replaceCharacter ('\\', '/');
  81. }
  82. String windowsStylePath (const String& path)
  83. {
  84. return path.replaceCharacter ('/', '\\');
  85. }
  86. String appendPath (const String& path, const String& subpath)
  87. {
  88. if (File::isAbsolutePath (subpath)
  89. || subpath.startsWithChar ('$')
  90. || subpath.startsWithChar ('~')
  91. || (CharacterFunctions::isLetter (subpath[0]) && subpath[1] == ':'))
  92. return subpath.replaceCharacter ('\\', '/');
  93. String path1 (path.replaceCharacter ('\\', '/'));
  94. if (! path1.endsWithChar ('/'))
  95. path1 << '/';
  96. return path1 + subpath.replaceCharacter ('\\', '/');
  97. }
  98. bool shouldPathsBeRelative (String path1, String path2)
  99. {
  100. path1 = unixStylePath (path1);
  101. path2 = unixStylePath (path2);
  102. const int len = jmin (path1.length(), path2.length());
  103. int commonBitLength = 0;
  104. for (int i = 0; i < len; ++i)
  105. {
  106. if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i]))
  107. break;
  108. ++commonBitLength;
  109. }
  110. return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty();
  111. }
  112. }