PageRenderTime 15ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/streams/file.cpp

http://github.com/mozy/mordor
C++ | 107 lines | 97 code | 9 blank | 1 comment | 23 complexity | b04c4361b503368574cc885766777213 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright (c) 2009 - Mozy, Inc.
  2. #include "file.h"
  3. #include "mordor/assert.h"
  4. #include "mordor/string.h"
  5. namespace Mordor {
  6. static Logger::ptr g_log = Log::lookup("mordor:streams:file");
  7. FileStream::FileStream()
  8. : m_supportsRead(false),
  9. m_supportsWrite(false),
  10. m_supportsSeek(false)
  11. {}
  12. void
  13. FileStream::init(const std::string &path, AccessFlags accessFlags,
  14. CreateFlags createFlags, IOManager *ioManager, Scheduler *scheduler)
  15. {
  16. NativeHandle handle;
  17. #ifdef WINDOWS
  18. DWORD access = 0;
  19. if (accessFlags & READ)
  20. access |= GENERIC_READ;
  21. if (accessFlags & WRITE)
  22. access |= GENERIC_WRITE;
  23. if (accessFlags == APPEND)
  24. access = FILE_APPEND_DATA | SYNCHRONIZE;
  25. DWORD flags = 0;
  26. if (createFlags & DELETE_ON_CLOSE) {
  27. flags |= FILE_FLAG_DELETE_ON_CLOSE;
  28. createFlags = (CreateFlags)(createFlags & ~DELETE_ON_CLOSE);
  29. }
  30. if (ioManager)
  31. flags |= FILE_FLAG_OVERLAPPED;
  32. MORDOR_ASSERT(createFlags >= CREATE_NEW && createFlags <= TRUNCATE_EXISTING);
  33. unsigned long shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
  34. handle = ::CreateFileW(Mordor::toUtf16(path).c_str(), access, shareMode, NULL, createFlags, flags, NULL);
  35. error_t error = lastError();
  36. MORDOR_LOG_VERBOSE(g_log) << "CreateFileW(" << path << ", "
  37. << access << ", " << createFlags << ", " << flags << "): " << handle
  38. << " (" << error << ")";
  39. if (handle == INVALID_HANDLE_VALUE) {
  40. try {
  41. MORDOR_THROW_EXCEPTION_FROM_ERROR_API(error, "CreateFileW");
  42. } catch (boost::exception &ex) {
  43. ex << boost::errinfo_file_name(path);
  44. throw;
  45. }
  46. }
  47. #else
  48. int oflags = (int)accessFlags;
  49. switch (createFlags & ~DELETE_ON_CLOSE) {
  50. case OPEN:
  51. break;
  52. case CREATE:
  53. oflags |= O_CREAT | O_EXCL;
  54. break;
  55. case OPEN_OR_CREATE:
  56. oflags |= O_CREAT;
  57. break;
  58. case OVERWRITE:
  59. oflags |= O_TRUNC;
  60. break;
  61. case OVERWRITE_OR_CREATE:
  62. oflags |= O_CREAT | O_TRUNC;
  63. break;
  64. default:
  65. MORDOR_NOTREACHED();
  66. }
  67. handle = open(path.c_str(), oflags, 0777);
  68. error_t error = lastError();
  69. MORDOR_LOG_VERBOSE(g_log) << "open(" << path << ", " << oflags << "): "
  70. << handle << " (" << error << ")";
  71. if (handle < 0) {
  72. try {
  73. MORDOR_THROW_EXCEPTION_FROM_ERROR_API(error, "open");
  74. } catch (boost::exception &ex) {
  75. ex << boost::errinfo_file_name(path);
  76. throw;
  77. }
  78. }
  79. if (createFlags & DELETE_ON_CLOSE) {
  80. int rc = unlink(path.c_str());
  81. if (rc != 0) {
  82. error_t error = lastError();
  83. ::close(handle);
  84. MORDOR_THROW_EXCEPTION_FROM_ERROR_API(error, "unlink");
  85. }
  86. }
  87. #endif
  88. NativeStream::init(handle, ioManager, scheduler);
  89. setSupportFlags(accessFlags);
  90. m_path = path;
  91. }
  92. void FileStream::setSupportFlags(AccessFlags accessFlags)
  93. {
  94. m_supportsRead = accessFlags == READ || accessFlags == READWRITE;
  95. m_supportsWrite = accessFlags == WRITE || accessFlags == READWRITE || accessFlags == APPEND;
  96. m_supportsSeek = accessFlags != APPEND;
  97. }
  98. }