mirror of
https://github.com/izzy2lost/cpython.git
synced 2026-03-10 11:29:24 -07:00
Initial commit
This commit is contained in:
174
win8app/python34/python34.cpp
Normal file
174
win8app/python34/python34.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "python34.h"
|
||||
#include "Python.h"
|
||||
#include <ppltasks.h>
|
||||
#include <inspectable.h>
|
||||
#include <wrl.h>
|
||||
#include <robuffer.h>
|
||||
#include <windows.storage.streams.h>
|
||||
|
||||
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::Storage::Streams;
|
||||
using namespace Windows::Security::Cryptography;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Platform;
|
||||
using namespace Concurrency;
|
||||
|
||||
namespace python34 {
|
||||
class PyBytesBuffer:
|
||||
public RuntimeClass<RuntimeClassFlags<RuntimeClassType::WinRtClassicComMix>,
|
||||
ABI::Windows::Storage::Streams::IBuffer,
|
||||
IBufferByteAccess>
|
||||
{
|
||||
public:
|
||||
PyObject *data;
|
||||
int length;
|
||||
virtual ~PyBytesBuffer()
|
||||
{
|
||||
Py_DECREF(data);
|
||||
}
|
||||
|
||||
STDMETHODIMP RuntimeClassInitialize(PyObject *data)
|
||||
{
|
||||
Py_INCREF(data);
|
||||
this->data = data;
|
||||
length = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Buffer(byte **value)
|
||||
{
|
||||
*value = (byte*)PyBytes_AsString(data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP get_Capacity(UINT32 *value)
|
||||
{
|
||||
*value = PyBytes_Size(data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP get_Length(UINT32 *value)
|
||||
{
|
||||
*value = length;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP put_Length(UINT32 value)
|
||||
{
|
||||
length = value;
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
}
|
||||
using namespace python34;
|
||||
|
||||
extern "C" {
|
||||
|
||||
void win32_urandom(unsigned char* buffer, Py_ssize_t size, int raise)
|
||||
{
|
||||
IBuffer^ data = CryptographicBuffer::GenerateRandom(size);
|
||||
Array<unsigned char>^ data2;
|
||||
CryptographicBuffer::CopyToByteArray(data, &data2);
|
||||
for(int i=0; i < size; i++)
|
||||
buffer[i] = data2[i];
|
||||
}
|
||||
|
||||
/* Temporary wrapper for local app data store. Will be replaced with generic wrapping later.
|
||||
Only modes "r" and "w" are supported. */
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
IInputStream^ item;
|
||||
} iinputstream;
|
||||
|
||||
|
||||
static PyObject*
|
||||
iinputstream_read(PyObject *self, PyObject* args)
|
||||
{
|
||||
int size;
|
||||
if (!PyArg_ParseTuple(args, "i", &size))
|
||||
return NULL;
|
||||
|
||||
PyObject *result = PyBytes_FromStringAndSize(NULL, size);
|
||||
if (!result)
|
||||
return NULL;
|
||||
ComPtr<PyBytesBuffer> native;
|
||||
Microsoft::WRL::Details::MakeAndInitialize<PyBytesBuffer>(&native, result);
|
||||
auto iinspectable = (IInspectable *)reinterpret_cast<IInspectable *>(native.Get());
|
||||
Streams::IBuffer ^buffer = reinterpret_cast<Streams::IBuffer ^>(iinspectable);
|
||||
create_task(((iinputstream*)self)->item->ReadAsync(buffer, size, InputStreamOptions::None)).wait();
|
||||
_PyBytes_Resize(&result, buffer->Length);
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyMethodDef iinputstream_methods[] = {
|
||||
{"read", iinputstream_read},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static PyTypeObject istoragefile_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"istoragefile", /* tp_name */
|
||||
sizeof(iinputstream), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||
"WinRT file", /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
};
|
||||
|
||||
static PyObject*
|
||||
new_istorageitem(IRandomAccessStream^ item)
|
||||
{
|
||||
istoragefile_Type.tp_new = PyType_GenericNew;
|
||||
if (!PyType_Ready(&istoragefile_Type))
|
||||
return NULL;
|
||||
PyObject *result = istoragefile_Type.tp_alloc(&istoragefile_Type, 0);
|
||||
if (!result)
|
||||
return NULL;
|
||||
((iinputstream*)result)->item = item;
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
local_open(PyObject *self, PyObject* args)
|
||||
{
|
||||
wchar_t *name, *mode;
|
||||
if (!PyArg_ParseTuple(args, "SS", &name, &mode))
|
||||
return NULL;
|
||||
StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;
|
||||
if (mode[0] == L'r') {
|
||||
String ^sname = ref new String(name);
|
||||
StorageFile^ item = create_task(localFolder->GetFileAsync(sname)).get();
|
||||
if (item == nullptr) {
|
||||
PyErr_SetString(PyExc_OSError, "File not found");
|
||||
return NULL;
|
||||
}
|
||||
auto result = create_task(item->OpenReadAsync()).get();
|
||||
return new_istorageitem(result);
|
||||
}
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
Reference in New Issue
Block a user