⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winfile.cxx

📁 c-smile 一个语法类似与JS 又有点像C++的 编译器
💻 CXX
字号:
//-< WINFILE.CXX >---------------------------------------------------*--------*
// SAL                       Version 1.0         (c) 1997  GARRET    *     ?  *
// (System Abstraction Layer)                                        *   /\|  *
//                                                                   *  /  \  *
//                          Created:      7-Jan-97    K.A. Knizhnik  * / [] \ *
//                          Last update: 21-Nov-98    K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// File implementation for Windows
//-------------------------------------------------------------------*--------*

#include "mmapfile.h"

namespace sal {

#define BAD_POS 0xFFFFFFFF // returned by SetFilePointer and GetFileSize

local int win_access_mode[] = {
    GENERIC_READ, GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE 
};

local int win_open_flags[] = {
    OPEN_EXISTING, TRUNCATE_EXISTING, OPEN_ALWAYS, CREATE_ALWAYS
};

local int win_open_attrs[] = {
    FILE_FLAG_SEQUENTIAL_SCAN,
    FILE_FLAG_SEQUENTIAL_SCAN|FILE_FLAG_WRITE_THROUGH, 
    FILE_FLAG_RANDOM_ACCESS,
    FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH,
};

local int win_page_access[] = {
    PAGE_READONLY, PAGE_READWRITE, PAGE_READWRITE 
};

local int win_map_access[] = {
    FILE_MAP_READ, FILE_MAP_WRITE, FILE_MAP_ALL_ACCESS 
};

class OS_info : public OSVERSIONINFO { 
  public: 
    OS_info() { 
	dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(this);
    }
};

static OS_info osinfo;
	

local file::iop_status get_system_error()
{
    int error = GetLastError();
    switch (error) { 
      case ERROR_HANDLE_EOF:
        return file::end_of_file;
      case NO_ERROR:
        return file::ok;
    }
    return file::iop_status(error);
} 

file::iop_status os_file::set_position(fposi_t pos,whence_mode wm)
{
    if (opened) { 
	LONG high_pos = nat8_high_part(pos); 
        if (SetFilePointer(fd, nat8_low_part(pos), &high_pos, wm)
            == BAD_POS)
        {
            return get_system_error();
        }
        return ok;
    }
    return not_opened; 
}

file::iop_status os_file::get_position(fposi_t& pos)
{
    if (opened) { 
        LONG  high_pos = 0;
        DWORD low_pos = SetFilePointer(fd, 0, &high_pos, FILE_CURRENT);
	pos = cons_nat8(high_pos, low_pos);	
        if (low_pos == BAD_POS) {
            return get_system_error();
        }
        return ok;
    }
    return not_opened; 
} 

file::iop_status os_file::read(void* buf, size_t size)
{  
    if (opened) { 
	
        return ReadFile(fd, buf, size, &bytes_affected, NULL)
            ? size == bytes_affected ? ok : end_of_file
            : get_system_error();
    } else {
	return not_opened;
    }
}

file::iop_status os_file::write(void const* buf, size_t size)
{  
    if (opened) {  
	
	return WriteFile(fd,buf, size, &bytes_affected, NULL) 
	    ? (DWORD)size == bytes_affected ? ok : end_of_file  
	    : get_system_error();
    } else { 
	return not_opened;
    }
}

file::iop_status os_file::read(fposi_t pos, void* buf, size_t size) 
{
    if (opened) { 
	
	if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { 
	    OVERLAPPED Overlapped;
	    Overlapped.Offset = nat8_low_part(pos);
	    Overlapped.OffsetHigh = nat8_high_part(pos);
            Overlapped.hEvent = NULL;
	    return ReadFile(fd, buf, size, &bytes_affected, &Overlapped)
		? size == bytes_affected ? ok : end_of_file
		: get_system_error(); 
	} else { 
	    critical_section cs(guard);
	    LONG high_pos = nat8_high_part(pos); 
            if (SetFilePointer(fd, nat8_low_part(pos), &high_pos, FILE_BEGIN)
                == BAD_POS)
            {
                iop_status rc = get_system_error();
                if (rc != ok) {
                    return rc;
                }
	    }
            boolean success = ReadFile(fd, buf, size, &bytes_affected, NULL);
	    return success ? size == bytes_affected ? ok : end_of_file
		: get_system_error();
	}
    } else { 
	return not_opened;
    }
}

file::iop_status os_file::write(fposi_t pos, void const* buf, size_t size) 
{
    if (opened) { 
	
	if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
	    OVERLAPPED Overlapped;
	    Overlapped.Offset = nat8_low_part(pos);
	    Overlapped.OffsetHigh = nat8_high_part(pos);
	    Overlapped.hEvent = NULL;
	    return WriteFile(fd, buf, size, &bytes_affected, &Overlapped)
		? size == bytes_affected ? ok : end_of_file
		: get_system_error(); 
	} else { 
	    critical_section cs(guard);
	    LONG high_pos = nat8_high_part(pos); 
            if (SetFilePointer(fd, nat8_low_part(pos), &high_pos, FILE_BEGIN)
                == BAD_POS)
            {
                iop_status rc = get_system_error();
                if (rc != ok) {
                    return rc;
                }
	    }
            boolean success = WriteFile(fd, buf, size, &bytes_affected, NULL);
	    return success ? size == bytes_affected ? ok : end_of_file
		: get_system_error();
	}
    } else { 
	return not_opened;
    }
}

file::iop_status os_file::close()
{
    if (opened) { 
	opened = False;
        return CloseHandle(fd) ? ok : get_system_error();
    } 
    return ok;
}

file::iop_status os_file::open(access_mode mode, int flags)
{
    close();
    assert(name != NULL); 
    fd = CreateFile(name, win_access_mode[mode],
		    (flags & fo_exclusive) ? 0 : (flags & fo_shared) 
		    ? FILE_SHARE_READ : FILE_SHARE_READ|FILE_SHARE_WRITE, 
		    NULL, win_open_flags[flags & (fo_truncate|fo_create)],
		    win_open_attrs[(flags & (fo_sync|fo_random)) >> 2],
		    NULL); 
    this->mode = mode;
    this->flags = flags;
    if (fd == INVALID_HANDLE_VALUE) {
        return get_system_error();
    } else { 
	opened = True;
	return ok;
    }
}

file::iop_status os_file::remove()
{
    close();
    return DeleteFile(name) 
	? ok : get_system_error();
}

char const* os_file::get_name() const 
{ 
    return name;
}

file::iop_status os_file::set_name(char const* new_name) 
{
    iop_status status = close();
    if (status == ok) { 
	if (new_name == NULL) { 
	    delete[] name;
	    name = NULL; 
	} else { 
	    if (name != NULL) { 
		if (strcmp(name, new_name) != 0) { 
                    if (MoveFile(name, new_name)) {
			delete[] name;
			name = strdup(new_name);
		    } else {
			return get_system_error();
		    }
		}
	    } else { 
		name = strdup(new_name);
	    }
	}
    }
    return status;
}

file::iop_status os_file::get_size(fsize_t& size) const
{
    if (opened) { 
	DWORD high_size;
        DWORD low_size = GetFileSize(fd, &high_size);
	size = cons_nat8(high_size, low_size);
        if (low_size == BAD_POS) {
            return get_system_error();
        }
	return ok;
    } else {
	return not_opened;
    }
}

file::iop_status os_file::set_size(fsize_t size)
{
    if (opened) { 
	LONG high_part = nat8_high_part(size); 
        if (SetFilePointer(fd, nat8_low_part(size), &high_part, FILE_BEGIN)
            != BAD_POS || get_system_error() == ok)
        {
            if (SetEndOfFile(fd)) {
		return ok;
	    }
	}
	return get_system_error();
    } else {
        return not_opened;
    }
}

file::iop_status os_file::flush()
{
    if (opened) { 
	return FlushFileBuffers(fd) ? ok : get_system_error();
    } else {
	return not_opened;
    }
}

void os_file::get_error_text(iop_status code, char* buf, size_t buf_size) const
{
    int len;
    switch (code) { 
      case ok:
	strncpy(buf, "Ok", buf_size);
	break;
      case not_opened:
        strncpy(buf, "file not opened", buf_size);
	break;
      case end_of_file:
	strncpy(buf, "operation not completly finished", buf_size);
	break;
      default:
        len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
		      NULL,
		      code,
		      0,
		      buf,
		      buf_size,
		      NULL);
	if (len == 0) { 
	    char errcode[64];
	    sprintf(errcode, "unknown error code %u", code);
	    strncpy(buf, errcode, buf_size);
	}
    }
}

size_t os_file::get_disk_block_size()
{
    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    return sysinfo.dwPageSize;
}

void* os_file::allocate_disk_buffer(size_t size)
{
    return VirtualAlloc(NULL, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
}

void  os_file::free_disk_buffer(void* buf)
{
    VirtualFree(buf, 0, MEM_RELEASE);
}

os_file::os_file(const char* name)
{
    opened = False;
    this->name = name ? strdup(name) : (char*)0; 
}


os_file::~os_file() 
{ 
    close();
    delete[] name; 
}

//
// Mapped on memory file
// 

file::iop_status mmap_file::open(access_mode mode, int flags)
{ 
    iop_status status = os_file::open(mode, flags);
    if (status == ok) { 
	DWORD high_size;
        DWORD size = GetFileSize(fd, &high_size);
        if (size == BAD_POS && (status = get_system_error()) != ok) {
            os_file::close();
	    return status;
        }
        assert(high_size == 0);

        mmap_size = (size < init_size) ? init_size : size;
        md = CreateFileMapping(fd, NULL,
			       win_page_access[mode],
                               0, mmap_size, NULL);
	if (md == NULL) { 
	    status = get_system_error();
	    os_file::close();
	    return status;
	}
	mmap_addr = (char*)MapViewOfFile(md, win_map_access[mode], 0, 0, 0);
	if (mmap_addr == NULL) { 
	    status = get_system_error();
	    os_file::close();
	    return status;
	}
	if (osinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) { 
	    // Windows 95 doesn't initialize pages
	    memset(mmap_addr+size, 0, mmap_size - size);
	}
    }
    return status; 
}

file::iop_status mmap_file::close()
{
    if (opened) { 
	if (!UnmapViewOfFile(mmap_addr) || !CloseHandle(md)) { 
	    return get_system_error();
	} 
	return os_file::close();
    }
    return ok;
}

file::iop_status mmap_file::set_size(fsize_t size)
{
    if (opened) { 
	iop_status status;
	size_t new_size = size_t(size);
	assert(size == new_size); // no truncation 

	if (new_size > mmap_size) { 
	    if (!UnmapViewOfFile(mmap_addr) || !CloseHandle(md)) { 
		return get_system_error();
	    } 
	    md = CreateFileMapping(fd, NULL, 
				   win_page_access[mode],
				   0, new_size, NULL);
	    if (md == NULL) { 
		status = get_system_error();
		os_file::close();
		return status;
	    }
	    mmap_addr = (char*)MapViewOfFile(md, win_map_access[mode], 
					     0, 0, 0);
	    if (mmap_addr == NULL) { 
		status = get_system_error();
		os_file::close();
		return status;
	    }
	    if (osinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) {
		// Windows 95 doesn't initialize pages
		memset(mmap_addr+mmap_size, 0, new_size - mmap_size);
	    } 
	    mmap_size = new_size;
	} 
	return ok;
    } else { 
	return not_opened;
    }
}

file::iop_status mmap_file::get_size(fsize_t& size) const
{
    if (opened) { 
	size = mmap_size;
	return ok;
    } else { 
	return not_opened;
    }
}

file::iop_status mmap_file::flush()
{
    if (opened) { 
	return FlushViewOfFile(mmap_addr, mmap_size)
	    ? ok : get_system_error();
    } else { 
	return not_opened;
    }	
}

};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -