summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/file/winrtptty.cpp
blob: cda1f128503abf54754128838019aef535523de3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// license:BSD-3-Clause
// copyright-holders:Aaron Giles, Vas Crabb


#include "winrtfile.h"

#include "strconv.h"

#include <cassert>

#include <windows.h>
#include <cstdlib>
#include <cstring>


namespace {
char const *const winfile_ptty_identifier = "\\\\.\\pipe\\";


class win_osd_ptty : public osd_file
{
public:
	win_osd_ptty(win_osd_ptty const &) = delete;
	win_osd_ptty(win_osd_ptty &&) = delete;
	win_osd_ptty& operator=(win_osd_ptty const &) = delete;
	win_osd_ptty& operator=(win_osd_ptty &&) = delete;

	win_osd_ptty(HANDLE handle) : m_handle(handle)
	{
		assert(m_handle);
		assert(INVALID_HANDLE_VALUE != m_handle);
	}

	~win_osd_ptty()
	{
	}

	virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
	{
		DWORD bytes_read;
		if (!ReadFile(m_handle, buffer, count, &bytes_read, nullptr))
			return win_error_to_file_error(GetLastError());

		actual = bytes_read;
		return error::NONE;
	}

	virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
	{
		DWORD bytes_written;
		if (!WriteFile(m_handle, buffer, count, &bytes_written, nullptr))
			return win_error_to_file_error(GetLastError());

		actual = bytes_written;
		return error::NONE;
	}

	virtual error truncate(std::uint64_t offset) override
	{
		// doesn't make sense for a PTTY
		return error::INVALID_ACCESS;
	}

	virtual error flush() override
	{
		// don't want to wait for client to read all data as implied by FlushFileBuffers
		return error::NONE;
	}

private:
	HANDLE m_handle;
};

} // anonymous namespace


bool win_check_ptty_path(std::string const &path)
{
	if (strncmp(path.c_str(), winfile_ptty_identifier, strlen(winfile_ptty_identifier)) == 0) return true;
	return false;
}


osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
{
	return osd_file::error::ACCESS_DENIED;
}
s="n">text = ("X"):rep(lz._TEST_BUFSIZ); local deflated = lz.deflate()(text, 'finish') local inflated = {} local inflator = lz.inflate() for i=1,#deflated do local part = inflator(deflated:sub(i,i)) table.insert(inflated, part) end inflated = table.concat(inflated) ok(inflated == text, "Expected " .. #text .. " Xs got " .. #inflated) end function test_basic() local test_string = "abcdefghijklmnopqrstuv" ok(lz.inflate()(lz.deflate()(), "finish") == "") -- Input to deflate is same as output to inflate: local deflated = lz.deflate()(test_string, "finish") local inflated = lz.inflate()(deflated, "finish") ok(test_string == inflated, "'" .. tostring(test_string) .. "' == '" .. tostring(inflated) .. "'") end function test_large() -- Try a larger string: local numbers = "" for i=1, 100 do numbers = numbers .. string.format("%3d", i) end local numbers_table = {} for i=1, 10000 do numbers_table[i] = numbers end local test_string = table.concat(numbers_table, "\n") local deflated = lz.deflate()(test_string, "finish") local inflated = lz.inflate()(deflated, "finish") ok(test_string == inflated, "large string") end function test_no_input() local stream = lz.deflate() local deflated = stream("") deflated = deflated .. stream("") deflated = deflated .. stream(nil, "finish") ok("" == lz.inflate()(deflated, "finish"), "empty string") end function test_invalid_input() local stream = lz.inflate() local isok, err = pcall( function() stream("bad input") end) ok(not isok) ok(string.find(err, "^InvalidInput"), string.format("InvalidInput error (%s)", err)) end function test_streaming() local shrink = lz.deflate(lz.BEST_COMPRESSION) local enlarge = lz.inflate() local expected = {} local got = {} local chant = "Isn't He great, isn't He wonderful?\n" for i=1,100 do if ( i == 100 ) then chant = nil print "EOF round" end local shrink_part, shrink_eof = shrink(chant) local enlarge_part, enlarge_eof = enlarge(shrink_part) if ( i == 100 ) then if not shrink_eof then error("expected eof after shrinking flush") end if not enlarge_eof then error("expected eof after enlarging") end else if shrink_eof then error("unexpected eof after shrinking") end if enlarge_eof then error("unexpected eof after enlarging") end end if enlarge_part then table.insert(got, enlarge_part) end if chant then table.insert(expected, chant) end end ok(table.concat(got) == table.concat(expected), "streaming works") end function test_illegal_state() local stream = lz.deflate() stream("abc") stream() -- eof/close local _, emsg = pcall( function() stream("printing on 'closed' handle") end) ok(string.find(emsg, "^IllegalState"), string.format("IllegalState error (%s)", emsg)) local enlarge = lz.inflate() end function test_checksum() for _, factory in pairs{lz.crc32, lz.adler32} do local csum = factory()("one two") -- Multiple calls: local compute = factory() compute("one") assert(csum == compute(" two")) -- Multiple compute_checksums joined: local compute1, compute2 = factory(), factory() compute1("one") compute2(" two") assert(csum == compute1(compute2)) end end function test_version() local major, minor, patch = lz.version() ok(1 == major, "major version 1 == " .. major); ok(type(minor) == "number", "minor version is number (" .. minor .. ")") ok(type(patch) == "number", "patch version is number (" .. patch .. ")") end main()