aboutsummaryrefslogtreecommitdiff
path: root/src/leveldb/util/env_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/leveldb/util/env_win.cc')
-rw-r--r--src/leveldb/util/env_win.cc1031
1 files changed, 0 insertions, 1031 deletions
diff --git a/src/leveldb/util/env_win.cc b/src/leveldb/util/env_win.cc
deleted file mode 100644
index ef2ecae830..0000000000
--- a/src/leveldb/util/env_win.cc
+++ /dev/null
@@ -1,1031 +0,0 @@
-// This file contains source that originates from:
-// http://code.google.com/p/leveldbwin/source/browse/trunk/win32_impl_src/env_win32.h
-// http://code.google.com/p/leveldbwin/source/browse/trunk/win32_impl_src/port_win32.cc
-// Those files dont' have any explict license headers but the
-// project (http://code.google.com/p/leveldbwin/) lists the 'New BSD License'
-// as the license.
-#if defined(LEVELDB_PLATFORM_WINDOWS)
-#include <map>
-
-
-#include "leveldb/env.h"
-
-#include "port/port.h"
-#include "leveldb/slice.h"
-#include "util/logging.h"
-
-#include <shlwapi.h>
-#include <process.h>
-#include <cstring>
-#include <stdio.h>
-#include <errno.h>
-#include <io.h>
-#include <algorithm>
-
-#ifdef max
-#undef max
-#endif
-
-#ifndef va_copy
-#define va_copy(d,s) ((d) = (s))
-#endif
-
-#if defined DeleteFile
-#undef DeleteFile
-#endif
-
-//Declarations
-namespace leveldb
-{
-
-namespace Win32
-{
-
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&); \
- void operator=(const TypeName&)
-
-std::string GetCurrentDir();
-std::wstring GetCurrentDirW();
-
-static const std::string CurrentDir = GetCurrentDir();
-static const std::wstring CurrentDirW = GetCurrentDirW();
-
-std::string& ModifyPath(std::string& path);
-std::wstring& ModifyPath(std::wstring& path);
-
-std::string GetLastErrSz();
-std::wstring GetLastErrSzW();
-
-size_t GetPageSize();
-
-typedef void (*ScheduleProc)(void*) ;
-
-struct WorkItemWrapper
-{
- WorkItemWrapper(ScheduleProc proc_,void* content_);
- ScheduleProc proc;
- void* pContent;
-};
-
-DWORD WINAPI WorkItemWrapperProc(LPVOID pContent);
-
-class Win32SequentialFile : public SequentialFile
-{
-public:
- friend class Win32Env;
- virtual ~Win32SequentialFile();
- virtual Status Read(size_t n, Slice* result, char* scratch);
- virtual Status Skip(uint64_t n);
- BOOL isEnable();
-private:
- BOOL _Init();
- void _CleanUp();
- Win32SequentialFile(const std::string& fname);
- std::string _filename;
- ::HANDLE _hFile;
- DISALLOW_COPY_AND_ASSIGN(Win32SequentialFile);
-};
-
-class Win32RandomAccessFile : public RandomAccessFile
-{
-public:
- friend class Win32Env;
- virtual ~Win32RandomAccessFile();
- virtual Status Read(uint64_t offset, size_t n, Slice* result,char* scratch) const;
- BOOL isEnable();
-private:
- BOOL _Init(LPCWSTR path);
- void _CleanUp();
- Win32RandomAccessFile(const std::string& fname);
- HANDLE _hFile;
- const std::string _filename;
- DISALLOW_COPY_AND_ASSIGN(Win32RandomAccessFile);
-};
-
-class Win32MapFile : public WritableFile
-{
-public:
- Win32MapFile(const std::string& fname);
-
- ~Win32MapFile();
- virtual Status Append(const Slice& data);
- virtual Status Close();
- virtual Status Flush();
- virtual Status Sync();
- BOOL isEnable();
-private:
- std::string _filename;
- HANDLE _hFile;
- size_t _page_size;
- size_t _map_size; // How much extra memory to map at a time
- char* _base; // The mapped region
- HANDLE _base_handle;
- char* _limit; // Limit of the mapped region
- char* _dst; // Where to write next (in range [base_,limit_])
- char* _last_sync; // Where have we synced up to
- uint64_t _file_offset; // Offset of base_ in file
- //LARGE_INTEGER file_offset_;
- // Have we done an munmap of unsynced data?
- bool _pending_sync;
-
- // Roundup x to a multiple of y
- static size_t _Roundup(size_t x, size_t y);
- size_t _TruncateToPageBoundary(size_t s);
- bool _UnmapCurrentRegion();
- bool _MapNewRegion();
- DISALLOW_COPY_AND_ASSIGN(Win32MapFile);
- BOOL _Init(LPCWSTR Path);
-};
-
-class Win32FileLock : public FileLock
-{
-public:
- friend class Win32Env;
- virtual ~Win32FileLock();
- BOOL isEnable();
-private:
- BOOL _Init(LPCWSTR path);
- void _CleanUp();
- Win32FileLock(const std::string& fname);
- HANDLE _hFile;
- std::string _filename;
- DISALLOW_COPY_AND_ASSIGN(Win32FileLock);
-};
-
-class Win32Logger : public Logger
-{
-public:
- friend class Win32Env;
- virtual ~Win32Logger();
- virtual void Logv(const char* format, va_list ap);
-private:
- explicit Win32Logger(WritableFile* pFile);
- WritableFile* _pFileProxy;
- DISALLOW_COPY_AND_ASSIGN(Win32Logger);
-};
-
-class Win32Env : public Env
-{
-public:
- Win32Env();
- virtual ~Win32Env();
- virtual Status NewSequentialFile(const std::string& fname,
- SequentialFile** result);
-
- virtual Status NewRandomAccessFile(const std::string& fname,
- RandomAccessFile** result);
- virtual Status NewWritableFile(const std::string& fname,
- WritableFile** result);
-
- virtual bool FileExists(const std::string& fname);
-
- virtual Status GetChildren(const std::string& dir,
- std::vector<std::string>* result);
-
- virtual Status DeleteFile(const std::string& fname);
-
- virtual Status CreateDir(const std::string& dirname);
-
- virtual Status DeleteDir(const std::string& dirname);
-
- virtual Status GetFileSize(const std::string& fname, uint64_t* file_size);
-
- virtual Status RenameFile(const std::string& src,
- const std::string& target);
-
- virtual Status LockFile(const std::string& fname, FileLock** lock);
-
- virtual Status UnlockFile(FileLock* lock);
-
- virtual void Schedule(
- void (*function)(void* arg),
- void* arg);
-
- virtual void StartThread(void (*function)(void* arg), void* arg);
-
- virtual Status GetTestDirectory(std::string* path);
-
- //virtual void Logv(WritableFile* log, const char* format, va_list ap);
-
- virtual Status NewLogger(const std::string& fname, Logger** result);
-
- virtual uint64_t NowMicros();
-
- virtual void SleepForMicroseconds(int micros);
-};
-
-void ToWidePath(const std::string& value, std::wstring& target) {
- wchar_t buffer[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, value.c_str(), -1, buffer, MAX_PATH);
- target = buffer;
-}
-
-void ToNarrowPath(const std::wstring& value, std::string& target) {
- char buffer[MAX_PATH];
- WideCharToMultiByte(CP_ACP, 0, value.c_str(), -1, buffer, MAX_PATH, NULL, NULL);
- target = buffer;
-}
-
-std::string GetCurrentDir()
-{
- CHAR path[MAX_PATH];
- ::GetModuleFileNameA(::GetModuleHandleA(NULL),path,MAX_PATH);
- *strrchr(path,'\\') = 0;
- return std::string(path);
-}
-
-std::wstring GetCurrentDirW()
-{
- WCHAR path[MAX_PATH];
- ::GetModuleFileNameW(::GetModuleHandleW(NULL),path,MAX_PATH);
- *wcsrchr(path,L'\\') = 0;
- return std::wstring(path);
-}
-
-std::string& ModifyPath(std::string& path)
-{
- if(path[0] == '/' || path[0] == '\\'){
- path = CurrentDir + path;
- }
- std::replace(path.begin(),path.end(),'/','\\');
-
- return path;
-}
-
-std::wstring& ModifyPath(std::wstring& path)
-{
- if(path[0] == L'/' || path[0] == L'\\'){
- path = CurrentDirW + path;
- }
- std::replace(path.begin(),path.end(),L'/',L'\\');
- return path;
-}
-
-std::string GetLastErrSz()
-{
- LPWSTR lpMsgBuf;
- FormatMessageW(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- 0, // Default language
- (LPWSTR) &lpMsgBuf,
- 0,
- NULL
- );
- std::string Err;
- ToNarrowPath(lpMsgBuf, Err);
- LocalFree( lpMsgBuf );
- return Err;
-}
-
-std::wstring GetLastErrSzW()
-{
- LPVOID lpMsgBuf;
- FormatMessageW(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- 0, // Default language
- (LPWSTR) &lpMsgBuf,
- 0,
- NULL
- );
- std::wstring Err = (LPCWSTR)lpMsgBuf;
- LocalFree(lpMsgBuf);
- return Err;
-}
-
-WorkItemWrapper::WorkItemWrapper( ScheduleProc proc_,void* content_ ) :
- proc(proc_),pContent(content_)
-{
-
-}
-
-DWORD WINAPI WorkItemWrapperProc(LPVOID pContent)
-{
- WorkItemWrapper* item = static_cast<WorkItemWrapper*>(pContent);
- ScheduleProc TempProc = item->proc;
- void* arg = item->pContent;
- delete item;
- TempProc(arg);
- return 0;
-}
-
-size_t GetPageSize()
-{
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- return std::max(si.dwPageSize,si.dwAllocationGranularity);
-}
-
-const size_t g_PageSize = GetPageSize();
-
-
-Win32SequentialFile::Win32SequentialFile( const std::string& fname ) :
- _filename(fname),_hFile(NULL)
-{
- _Init();
-}
-
-Win32SequentialFile::~Win32SequentialFile()
-{
- _CleanUp();
-}
-
-Status Win32SequentialFile::Read( size_t n, Slice* result, char* scratch )
-{
- Status sRet;
- DWORD hasRead = 0;
- if(_hFile && ReadFile(_hFile,scratch,n,&hasRead,NULL) ){
- *result = Slice(scratch,hasRead);
- } else {
- sRet = Status::IOError(_filename, Win32::GetLastErrSz() );
- }
- return sRet;
-}
-
-Status Win32SequentialFile::Skip( uint64_t n )
-{
- Status sRet;
- LARGE_INTEGER Move,NowPointer;
- Move.QuadPart = n;
- if(!SetFilePointerEx(_hFile,Move,&NowPointer,FILE_CURRENT)){
- sRet = Status::IOError(_filename,Win32::GetLastErrSz());
- }
- return sRet;
-}
-
-BOOL Win32SequentialFile::isEnable()
-{
- return _hFile ? TRUE : FALSE;
-}
-
-BOOL Win32SequentialFile::_Init()
-{
- std::wstring path;
- ToWidePath(_filename, path);
- _hFile = CreateFileW(path.c_str(),
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- return _hFile ? TRUE : FALSE;
-}
-
-void Win32SequentialFile::_CleanUp()
-{
- if(_hFile){
- CloseHandle(_hFile);
- _hFile = NULL;
- }
-}
-
-Win32RandomAccessFile::Win32RandomAccessFile( const std::string& fname ) :
- _filename(fname),_hFile(NULL)
-{
- std::wstring path;
- ToWidePath(fname, path);
- _Init( path.c_str() );
-}
-
-Win32RandomAccessFile::~Win32RandomAccessFile()
-{
- _CleanUp();
-}
-
-Status Win32RandomAccessFile::Read(uint64_t offset,size_t n,Slice* result,char* scratch) const
-{
- Status sRet;
- OVERLAPPED ol = {0};
- ZeroMemory(&ol,sizeof(ol));
- ol.Offset = (DWORD)offset;
- ol.OffsetHigh = (DWORD)(offset >> 32);
- DWORD hasRead = 0;
- if(!ReadFile(_hFile,scratch,n,&hasRead,&ol))
- sRet = Status::IOError(_filename,Win32::GetLastErrSz());
- else
- *result = Slice(scratch,hasRead);
- return sRet;
-}
-
-BOOL Win32RandomAccessFile::_Init( LPCWSTR path )
-{
- BOOL bRet = FALSE;
- if(!_hFile)
- _hFile = ::CreateFileW(path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,NULL);
- if(!_hFile || _hFile == INVALID_HANDLE_VALUE )
- _hFile = NULL;
- else
- bRet = TRUE;
- return bRet;
-}
-
-BOOL Win32RandomAccessFile::isEnable()
-{
- return _hFile ? TRUE : FALSE;
-}
-
-void Win32RandomAccessFile::_CleanUp()
-{
- if(_hFile){
- ::CloseHandle(_hFile);
- _hFile = NULL;
- }
-}
-
-size_t Win32MapFile::_Roundup( size_t x, size_t y )
-{
- return ((x + y - 1) / y) * y;
-}
-
-size_t Win32MapFile::_TruncateToPageBoundary( size_t s )
-{
- s -= (s & (_page_size - 1));
- assert((s % _page_size) == 0);
- return s;
-}
-
-bool Win32MapFile::_UnmapCurrentRegion()
-{
- bool result = true;
- if (_base != NULL) {
- if (_last_sync < _limit) {
- // Defer syncing this data until next Sync() call, if any
- _pending_sync = true;
- }
- if (!UnmapViewOfFile(_base) || !CloseHandle(_base_handle))
- result = false;
- _file_offset += _limit - _base;
- _base = NULL;
- _base_handle = NULL;
- _limit = NULL;
- _last_sync = NULL;
- _dst = NULL;
- // Increase the amount we map the next time, but capped at 1MB
- if (_map_size < (1<<20)) {
- _map_size *= 2;
- }
- }
- return result;
-}
-
-bool Win32MapFile::_MapNewRegion()
-{
- assert(_base == NULL);
- //LONG newSizeHigh = (LONG)((file_offset_ + map_size_) >> 32);
- //LONG newSizeLow = (LONG)((file_offset_ + map_size_) & 0xFFFFFFFF);
- DWORD off_hi = (DWORD)(_file_offset >> 32);
- DWORD off_lo = (DWORD)(_file_offset & 0xFFFFFFFF);
- LARGE_INTEGER newSize;
- newSize.QuadPart = _file_offset + _map_size;
- SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN);
- SetEndOfFile(_hFile);
-
- _base_handle = CreateFileMappingA(
- _hFile,
- NULL,
- PAGE_READWRITE,
- 0,
- 0,
- 0);
- if (_base_handle != NULL) {
- _base = (char*) MapViewOfFile(_base_handle,
- FILE_MAP_ALL_ACCESS,
- off_hi,
- off_lo,
- _map_size);
- if (_base != NULL) {
- _limit = _base + _map_size;
- _dst = _base;
- _last_sync = _base;
- return true;
- }
- }
- return false;
-}
-
-Win32MapFile::Win32MapFile( const std::string& fname) :
- _filename(fname),
- _hFile(NULL),
- _page_size(Win32::g_PageSize),
- _map_size(_Roundup(65536, Win32::g_PageSize)),
- _base(NULL),
- _base_handle(NULL),
- _limit(NULL),
- _dst(NULL),
- _last_sync(NULL),
- _file_offset(0),
- _pending_sync(false)
-{
- std::wstring path;
- ToWidePath(fname, path);
- _Init(path.c_str());
- assert((Win32::g_PageSize & (Win32::g_PageSize - 1)) == 0);
-}
-
-Status Win32MapFile::Append( const Slice& data )
-{
- const char* src = data.data();
- size_t left = data.size();
- Status s;
- while (left > 0) {
- assert(_base <= _dst);
- assert(_dst <= _limit);
- size_t avail = _limit - _dst;
- if (avail == 0) {
- if (!_UnmapCurrentRegion() ||
- !_MapNewRegion()) {
- return Status::IOError("WinMmapFile.Append::UnmapCurrentRegion or MapNewRegion: ", Win32::GetLastErrSz());
- }
- }
- size_t n = (left <= avail) ? left : avail;
- memcpy(_dst, src, n);
- _dst += n;
- src += n;
- left -= n;
- }
- return s;
-}
-
-Status Win32MapFile::Close()
-{
- Status s;
- size_t unused = _limit - _dst;
- if (!_UnmapCurrentRegion()) {
- s = Status::IOError("WinMmapFile.Close::UnmapCurrentRegion: ",Win32::GetLastErrSz());
- } else if (unused > 0) {
- // Trim the extra space at the end of the file
- LARGE_INTEGER newSize;
- newSize.QuadPart = _file_offset - unused;
- if (!SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN)) {
- s = Status::IOError("WinMmapFile.Close::SetFilePointer: ",Win32::GetLastErrSz());
- } else
- SetEndOfFile(_hFile);
- }
- if (!CloseHandle(_hFile)) {
- if (s.ok()) {
- s = Status::IOError("WinMmapFile.Close::CloseHandle: ", Win32::GetLastErrSz());
- }
- }
- _hFile = INVALID_HANDLE_VALUE;
- _base = NULL;
- _base_handle = NULL;
- _limit = NULL;
-
- return s;
-}
-
-Status Win32MapFile::Sync()
-{
- Status s;
- if (_pending_sync) {
- // Some unmapped data was not synced
- _pending_sync = false;
- if (!FlushFileBuffers(_hFile)) {
- s = Status::IOError("WinMmapFile.Sync::FlushFileBuffers: ",Win32::GetLastErrSz());
- }
- }
- if (_dst > _last_sync) {
- // Find the beginnings of the pages that contain the first and last
- // bytes to be synced.
- size_t p1 = _TruncateToPageBoundary(_last_sync - _base);
- size_t p2 = _TruncateToPageBoundary(_dst - _base - 1);
- _last_sync = _dst;
- if (!FlushViewOfFile(_base + p1, p2 - p1 + _page_size)) {
- s = Status::IOError("WinMmapFile.Sync::FlushViewOfFile: ",Win32::GetLastErrSz());
- }
- }
- return s;
-}
-
-Status Win32MapFile::Flush()
-{
- return Status::OK();
-}
-
-Win32MapFile::~Win32MapFile()
-{
- if (_hFile != INVALID_HANDLE_VALUE) {
- Win32MapFile::Close();
- }
-}
-
-BOOL Win32MapFile::_Init( LPCWSTR Path )
-{
- DWORD Flag = PathFileExistsW(Path) ? OPEN_EXISTING : CREATE_ALWAYS;
- _hFile = CreateFileW(Path,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
- NULL,
- Flag,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if(!_hFile || _hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- else
- return TRUE;
-}
-
-BOOL Win32MapFile::isEnable()
-{
- return _hFile ? TRUE : FALSE;
-}
-
-Win32FileLock::Win32FileLock( const std::string& fname ) :
- _hFile(NULL),_filename(fname)
-{
- std::wstring path;
- ToWidePath(fname, path);
- _Init(path.c_str());
-}
-
-Win32FileLock::~Win32FileLock()
-{
- _CleanUp();
-}
-
-BOOL Win32FileLock::_Init( LPCWSTR path )
-{
- BOOL bRet = FALSE;
- if(!_hFile)
- _hFile = ::CreateFileW(path,0,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
- if(!_hFile || _hFile == INVALID_HANDLE_VALUE ){
- _hFile = NULL;
- }
- else
- bRet = TRUE;
- return bRet;
-}
-
-void Win32FileLock::_CleanUp()
-{
- ::CloseHandle(_hFile);
- _hFile = NULL;
-}
-
-BOOL Win32FileLock::isEnable()
-{
- return _hFile ? TRUE : FALSE;
-}
-
-Win32Logger::Win32Logger(WritableFile* pFile) : _pFileProxy(pFile)
-{
- assert(_pFileProxy);
-}
-
-Win32Logger::~Win32Logger()
-{
- if(_pFileProxy)
- delete _pFileProxy;
-}
-
-void Win32Logger::Logv( const char* format, va_list ap )
-{
- uint64_t thread_id = ::GetCurrentThreadId();
-
- // We try twice: the first time with a fixed-size stack allocated buffer,
- // and the second time with a much larger dynamically allocated buffer.
- char buffer[500];
- for (int iter = 0; iter < 2; iter++) {
- char* base;
- int bufsize;
- if (iter == 0) {
- bufsize = sizeof(buffer);
- base = buffer;
- } else {
- bufsize = 30000;
- base = new char[bufsize];
- }
- char* p = base;
- char* limit = base + bufsize;
-
- SYSTEMTIME st;
- GetLocalTime(&st);
- p += snprintf(p, limit - p,
- "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ",
- int(st.wYear),
- int(st.wMonth),
- int(st.wDay),
- int(st.wHour),
- int(st.wMinute),
- int(st.wMinute),
- int(st.wMilliseconds),
- static_cast<long long unsigned int>(thread_id));
-
- // Print the message
- if (p < limit) {
- va_list backup_ap;
- va_copy(backup_ap, ap);
- p += vsnprintf(p, limit - p, format, backup_ap);
- va_end(backup_ap);
- }
-
- // Truncate to available space if necessary
- if (p >= limit) {
- if (iter == 0) {
- continue; // Try again with larger buffer
- } else {
- p = limit - 1;
- }
- }
-
- // Add newline if necessary
- if (p == base || p[-1] != '\n') {
- *p++ = '\n';
- }
-
- assert(p <= limit);
- DWORD hasWritten = 0;
- if(_pFileProxy){
- _pFileProxy->Append(Slice(base, p - base));
- _pFileProxy->Flush();
- }
- if (base != buffer) {
- delete[] base;
- }
- break;
- }
-}
-
-bool Win32Env::FileExists(const std::string& fname)
-{
- std::string path = fname;
- std::wstring wpath;
- ToWidePath(ModifyPath(path), wpath);
- return ::PathFileExistsW(wpath.c_str()) ? true : false;
-}
-
-Status Win32Env::GetChildren(const std::string& dir, std::vector<std::string>* result)
-{
- Status sRet;
- ::WIN32_FIND_DATAW wfd;
- std::string path = dir;
- ModifyPath(path);
- path += "\\*.*";
- std::wstring wpath;
- ToWidePath(path, wpath);
-
- ::HANDLE hFind = ::FindFirstFileW(wpath.c_str() ,&wfd);
- if(hFind && hFind != INVALID_HANDLE_VALUE){
- BOOL hasNext = TRUE;
- std::string child;
- while(hasNext){
- ToNarrowPath(wfd.cFileName, child);
- if(child != ".." && child != ".") {
- result->push_back(child);
- }
- hasNext = ::FindNextFileW(hFind,&wfd);
- }
- ::FindClose(hFind);
- }
- else
- sRet = Status::IOError(dir,"Could not get children.");
- return sRet;
-}
-
-void Win32Env::SleepForMicroseconds( int micros )
-{
- ::Sleep((micros + 999) /1000);
-}
-
-
-Status Win32Env::DeleteFile( const std::string& fname )
-{
- Status sRet;
- std::string path = fname;
- std::wstring wpath;
- ToWidePath(ModifyPath(path), wpath);
-
- if(!::DeleteFileW(wpath.c_str())) {
- sRet = Status::IOError(path, "Could not delete file.");
- }
- return sRet;
-}
-
-Status Win32Env::GetFileSize( const std::string& fname, uint64_t* file_size )
-{
- Status sRet;
- std::string path = fname;
- std::wstring wpath;
- ToWidePath(ModifyPath(path), wpath);
-
- HANDLE file = ::CreateFileW(wpath.c_str(),
- GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
- LARGE_INTEGER li;
- if(::GetFileSizeEx(file,&li)){
- *file_size = (uint64_t)li.QuadPart;
- }else
- sRet = Status::IOError(path,"Could not get the file size.");
- CloseHandle(file);
- return sRet;
-}
-
-Status Win32Env::RenameFile( const std::string& src, const std::string& target )
-{
- Status sRet;
- std::string src_path = src;
- std::wstring wsrc_path;
- ToWidePath(ModifyPath(src_path), wsrc_path);
- std::string target_path = target;
- std::wstring wtarget_path;
- ToWidePath(ModifyPath(target_path), wtarget_path);
-
- if(!MoveFileW(wsrc_path.c_str(), wtarget_path.c_str() ) ){
- DWORD err = GetLastError();
- if(err == 0x000000b7){
- if(!::DeleteFileW(wtarget_path.c_str() ) )
- sRet = Status::IOError(src, "Could not rename file.");
- else if(!::MoveFileW(wsrc_path.c_str(),
- wtarget_path.c_str() ) )
- sRet = Status::IOError(src, "Could not rename file.");
- }
- }
- return sRet;
-}
-
-Status Win32Env::LockFile( const std::string& fname, FileLock** lock )
-{
- Status sRet;
- std::string path = fname;
- ModifyPath(path);
- Win32FileLock* _lock = new Win32FileLock(path);
- if(!_lock->isEnable()){
- delete _lock;
- *lock = NULL;
- sRet = Status::IOError(path, "Could not lock file.");
- }
- else
- *lock = _lock;
- return sRet;
-}
-
-Status Win32Env::UnlockFile( FileLock* lock )
-{
- Status sRet;
- delete lock;
- return sRet;
-}
-
-void Win32Env::Schedule( void (*function)(void* arg), void* arg )
-{
- QueueUserWorkItem(Win32::WorkItemWrapperProc,
- new Win32::WorkItemWrapper(function,arg),
- WT_EXECUTEDEFAULT);
-}
-
-void Win32Env::StartThread( void (*function)(void* arg), void* arg )
-{
- ::_beginthread(function,0,arg);
-}
-
-Status Win32Env::GetTestDirectory( std::string* path )
-{
- Status sRet;
- WCHAR TempPath[MAX_PATH];
- ::GetTempPathW(MAX_PATH,TempPath);
- ToNarrowPath(TempPath, *path);
- path->append("leveldb\\test\\");
- ModifyPath(*path);
- return sRet;
-}
-
-uint64_t Win32Env::NowMicros()
-{
-#ifndef USE_VISTA_API
-#define GetTickCount64 GetTickCount
-#endif
- return (uint64_t)(GetTickCount64()*1000);
-}
-
-static Status CreateDirInner( const std::string& dirname )
-{
- Status sRet;
- DWORD attr = ::GetFileAttributes(dirname.c_str());
- if (attr == INVALID_FILE_ATTRIBUTES) { // doesn't exist:
- std::size_t slash = dirname.find_last_of("\\");
- if (slash != std::string::npos){
- sRet = CreateDirInner(dirname.substr(0, slash));
- if (!sRet.ok()) return sRet;
- }
- BOOL result = ::CreateDirectory(dirname.c_str(), NULL);
- if (result == FALSE) {
- sRet = Status::IOError(dirname, "Could not create directory.");
- return sRet;
- }
- }
- return sRet;
-}
-
-Status Win32Env::CreateDir( const std::string& dirname )
-{
- std::string path = dirname;
- if(path[path.length() - 1] != '\\'){
- path += '\\';
- }
- ModifyPath(path);
-
- return CreateDirInner(path);
-}
-
-Status Win32Env::DeleteDir( const std::string& dirname )
-{
- Status sRet;
- std::wstring path;
- ToWidePath(dirname, path);
- ModifyPath(path);
- if(!::RemoveDirectoryW( path.c_str() ) ){
- sRet = Status::IOError(dirname, "Could not delete directory.");
- }
- return sRet;
-}
-
-Status Win32Env::NewSequentialFile( const std::string& fname, SequentialFile** result )
-{
- Status sRet;
- std::string path = fname;
- ModifyPath(path);
- Win32SequentialFile* pFile = new Win32SequentialFile(path);
- if(pFile->isEnable()){
- *result = pFile;
- }else {
- delete pFile;
- sRet = Status::IOError(path, Win32::GetLastErrSz());
- }
- return sRet;
-}
-
-Status Win32Env::NewRandomAccessFile( const std::string& fname, RandomAccessFile** result )
-{
- Status sRet;
- std::string path = fname;
- Win32RandomAccessFile* pFile = new Win32RandomAccessFile(ModifyPath(path));
- if(!pFile->isEnable()){
- delete pFile;
- *result = NULL;
- sRet = Status::IOError(path, Win32::GetLastErrSz());
- }else
- *result = pFile;
- return sRet;
-}
-
-Status Win32Env::NewLogger( const std::string& fname, Logger** result )
-{
- Status sRet;
- std::string path = fname;
- Win32MapFile* pMapFile = new Win32MapFile(ModifyPath(path));
- if(!pMapFile->isEnable()){
- delete pMapFile;
- *result = NULL;
- sRet = Status::IOError(path,"could not create a logger.");
- }else
- *result = new Win32Logger(pMapFile);
- return sRet;
-}
-
-Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** result )
-{
- Status sRet;
- std::string path = fname;
- Win32MapFile* pFile = new Win32MapFile(ModifyPath(path));
- if(!pFile->isEnable()){
- *result = NULL;
- sRet = Status::IOError(fname,Win32::GetLastErrSz());
- }else
- *result = pFile;
- return sRet;
-}
-
-Win32Env::Win32Env()
-{
-
-}
-
-Win32Env::~Win32Env()
-{
-
-}
-
-
-} // Win32 namespace
-
-static port::OnceType once = LEVELDB_ONCE_INIT;
-static Env* default_env;
-static void InitDefaultEnv() { default_env = new Win32::Win32Env(); }
-
-Env* Env::Default() {
- port::InitOnce(&once, InitDefaultEnv);
- return default_env;
-}
-
-} // namespace leveldb
-
-#endif // defined(LEVELDB_PLATFORM_WINDOWS)