Пример #1
0
    def assertPyTuple_New_Works(self, length):
        allocs = []
        mapper = PythonMapper(GetAllocatingTestAllocator(allocs, []))

        typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject))
        mapper.RegisterData("PyTuple_Type", typeBlock)
        tuplePtr = mapper.PyTuple_New(length)
        expectedSize = Marshal.SizeOf(PyTupleObject) + (CPyMarshal.PtrSize * (length - 1))
        self.assertEquals(allocs, [(tuplePtr, expectedSize)], "bad alloc")
        tupleStruct = Marshal.PtrToStructure(tuplePtr, PyTupleObject)
        self.assertEquals(tupleStruct.ob_refcnt, 1, "bad refcount")
        self.assertEquals(tupleStruct.ob_type, mapper.PyTuple_Type, "bad type")
        self.assertEquals(tupleStruct.ob_size, length, "bad size")
        self.assertEquals(mapper.PyTuple_Size(tuplePtr), length, "should still work with uninitialised tuple imo")
        dataPtr = OffsetPtr(tuplePtr, Marshal.OffsetOf(PyTupleObject, "ob_item"))
        itemPtrs = []
        for i in range(length):
            self.assertEquals(CPyMarshal.ReadPtr(dataPtr), IntPtr.Zero, "item memory not zeroed")
            itemPtr = mapper.Store(i + 100)
            CPyMarshal.WritePtr(dataPtr, itemPtr)
            itemPtrs.append(itemPtr)
            dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize)

        immutableTuple = mapper.Retrieve(tuplePtr)
        self.assertEquals(immutableTuple, tuple(i + 100 for i in range(length)), "broken")

        tuplePtr2 = mapper.Store(immutableTuple)
        self.assertEquals(tuplePtr2, tuplePtr, "didn't realise already had this object stored")
        self.assertEquals(mapper.RefCount(tuplePtr), 2, "didn't incref")
        
        mapper.Dispose()
        Marshal.FreeHGlobal(typeBlock)
Пример #2
0
    def testStoreTupleCreatesTupleType(self):
        allocs = []
        mapper = PythonMapper(GetAllocatingTestAllocator(allocs, []))

        typeBlock = Marshal.AllocHGlobal(Marshal.SizeOf(PyTypeObject()))
        mapper.RegisterData("PyTuple_Type", typeBlock)

        theTuple = (0, 1, 2)
        tuplePtr = mapper.Store(theTuple)
        self.assertEquals(
            CPyMarshal.ReadPtrField(tuplePtr, PyTupleObject, "ob_type"),
            typeBlock, "wrong type")

        dataPtr = OffsetPtr(tuplePtr, Marshal.OffsetOf(PyTupleObject,
                                                       "ob_item"))
        for i in range(3):
            item = mapper.Retrieve(CPyMarshal.ReadPtr(dataPtr))
            self.assertEquals(item, i, "did not store data")
            dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize)

        tuplePtr2 = mapper.Store(theTuple)
        self.assertEquals(tuplePtr2, tuplePtr,
                          "didn't realise already had this tuple")
        self.assertEquals(mapper.RefCount(tuplePtr), 2, "didn't incref")

        mapper.Dispose()
        Marshal.FreeHGlobal(typeBlock)
Пример #3
0
    def testSomeItems(self):
        allocs = []
        mapper = PythonMapper(GetAllocatingTestAllocator(allocs, []))
        deallocTypes = CreateTypes(mapper)
        typeSpec = {
            "tp_basicsize": 32,
            "tp_itemsize": 64,
        }
        typePtr, deallocType = MakeTypePtr(mapper, typeSpec)
        
        del allocs[:]
        result = mapper.PyType_GenericAlloc(typePtr, 3)
        self.assertEquals(allocs, [(result, 224)], "allocated wrong")

        refcount = CPyMarshal.ReadIntField(result, PyObject, "ob_refcnt")
        self.assertEquals(refcount, 1, "bad initialisation")

        instanceType = CPyMarshal.ReadPtrField(result, PyObject, "ob_type")
        self.assertEquals(instanceType, typePtr, "bad type ptr")

        size = CPyMarshal.ReadIntField(result, PyVarObject, "ob_size")
        self.assertEquals(size, 3, "bad ob_size")
        
        headerSize = Marshal.SizeOf(PyVarObject)
        zerosPtr = OffsetPtr(result, headerSize)
        for i in range(224 - headerSize):
            self.assertEquals(CPyMarshal.ReadByte(zerosPtr), 0, "not zeroed")
            zerosPtr = OffsetPtr(zerosPtr, 1)
 
        mapper.Dispose()
        deallocTypes()
        deallocType()
Пример #4
0
 def CreateInstance(mapper, calls):
     tuplePtr = mapper.PyTuple_New(len(model))
     dataPtr = OffsetPtr(tuplePtr, Marshal.OffsetOf(PyTupleObject, "ob_item"))
     for i in range(len(model)):
         itemPtr = mapper.Store(model[i])
         itemPtrs.append(itemPtr)
         CPyMarshal.WritePtr(dataPtr, itemPtr)
         dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize)
     return tuplePtr
Пример #5
0
 def CreateInstance(mapper, calls):
     listPtr = mapper.Store([1, 2, 3])
     dataStore = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item")
     for _ in range(3):
         itemPtrs.append(CPyMarshal.ReadPtr(dataStore))
         dataStore = OffsetPtr(dataStore, CPyMarshal.PtrSize)
     return listPtr
Пример #6
0
 def testPyList_New_NonZeroLength(self):
     allocs = []
     mapper = PythonMapper(GetAllocatingTestAllocator(allocs, []))
     deallocTypes = CreateTypes(mapper)
     del allocs[:]
     
     SIZE = 27
     listPtr = mapper.PyList_New(SIZE)
     
     listStruct = Marshal.PtrToStructure(listPtr, PyListObject)
     self.assertEquals(listStruct.ob_refcnt, 1, "bad refcount")
     self.assertEquals(listStruct.ob_type, mapper.PyList_Type, "bad type")
     self.assertEquals(listStruct.ob_size, SIZE, "bad ob_size")
     self.assertEquals(listStruct.allocated, SIZE, "bad allocated")
     
     dataPtr = listStruct.ob_item
     self.assertNotEquals(dataPtr, IntPtr.Zero, "failed to allocate space for data")
     
     expectedAllocs = [(dataPtr, (SIZE * CPyMarshal.PtrSize)), (listPtr, Marshal.SizeOf(PyListObject))]
     self.assertEquals(set(allocs), set(expectedAllocs), "allocated wrong")
     
     for _ in range(SIZE):
         self.assertEquals(CPyMarshal.ReadPtr(dataPtr), IntPtr.Zero, "failed to zero memory")
         dataPtr = OffsetPtr(dataPtr, CPyMarshal.PtrSize)
     
     mapper.Dispose()
     deallocTypes()
Пример #7
0
 def testPyList_DeallocDecRefsItemsAndCallsCorrectFreeFunction(self):
     frees = []
     mapper = PythonMapper(GetAllocatingTestAllocator([], frees))
     deallocTypes = CreateTypes(mapper)
     
     calls = []
     def CustomFree(ptr):
         calls.append(ptr)
         mapper.PyObject_Free(listPtr)
     self.freeDgt = dgt_void_ptr(CustomFree)
     
     CPyMarshal.WriteFunctionPtrField(mapper.PyList_Type, PyTypeObject, "tp_free", self.freeDgt)
     
     listPtr = mapper.Store([1, 2, 3])
     itemPtrs = []
     dataStore = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item")
     for _ in range(3):
         itemPtrs.append(CPyMarshal.ReadPtr(dataStore))
         dataStore = OffsetPtr(dataStore, CPyMarshal.PtrSize)
     
     mapper.IC_PyList_Dealloc(listPtr)
     
     for itemPtr in itemPtrs:
         self.assertEquals(itemPtr in frees, True, "did not decref item")
     self.assertEquals(calls, [listPtr], "did not call type's free function")
     
     mapper.Dispose()
     deallocTypes()
Пример #8
0
    def testConvertPyFileToDescriptor(self, mapper, _):
        testDir = tempfile.mkdtemp()
        outFile = os.path.join(testDir, "test")
        pyFile = file(outFile, 'w')
        pyFile.write("I love streams ")
        pyFile.flush()

        fd = mapper.ConvertPyFileToDescriptor(pyFile)
        FILE = Unmanaged._fdopen(fd, "w")

        testStr = "and file descriptors!"
        testStrPtr = mapper.Store(testStr)
        testDataPtr = OffsetPtr(testStrPtr,
                                Marshal.OffsetOf(PyStringObject, "ob_sval"))

        self.assertTrue(
            Unmanaged.fwrite(testDataPtr, 1, len(testStr), FILE) > 0,
            "writing failed")
        Unmanaged.fflush(FILE)
        pyFile.close()

        stream = file(outFile, 'r')
        output = stream.read()
        stream.close()
        self.assertEquals(output, "I love streams and file descriptors!")
Пример #9
0
 def testIC_PyFile_AsFile_Write(self, mapper, addToCleanUp, _):
     testDir = tempfile.mkdtemp()
     addToCleanUp(lambda: shutil.rmtree(testDir))
     path = os.path.join(testDir, "test")
     
     testStr = "meh, string data"
     testLength = len(testStr)
     testStrPtr = mapper.Store(testStr)
     testDataPtr = OffsetPtr(testStrPtr, Marshal.OffsetOf(PyStringObject, "ob_sval"))
     
     filePtr = mapper.Store(open(path, 'w'))
     
     f = mapper.IC_PyFile_AsFile(filePtr)
     self.assertEquals(Unmanaged.fwrite(testDataPtr, 1, testLength, f), testLength, "didn't work")
     
     # nasty test: patch out PyObject_Free
     # the memory will not be deallocated, but the FILE handle should be
     
     calls = []
     def Free(ptr):
         calls.append(ptr)
     
     freeDgt = dgt_void_ptr(Free)
     CPyMarshal.WriteFunctionPtrField(mapper.PyFile_Type, PyTypeObject, 'tp_free', freeDgt)
     
     mapper.DecRef(filePtr)
     self.assertEquals(calls, [filePtr], 'failed to call tp_free function')
     
     mgdF = open(path)
     result = mgdF.read()
     self.assertEquals(result, testStr, "failed to write (got >>%s<<) -- deallocing filePtr did not close FILE" % result)
     mgdF.close()
Пример #10
0
    def assertStringObjectHasLength(self, strPtr, length):
        stringObject = Marshal.PtrToStructure(strPtr, PyStringObject)
        self.assertEquals(stringObject.ob_refcnt, 1, "unexpected refcount")
        self.assertEquals(stringObject.ob_size, length, "unexpected ob_size")
        self.assertEquals(stringObject.ob_shash, -1,
                          "unexpected currently-useless-field")
        self.assertEquals(stringObject.ob_sstate, 0,
                          "unexpected currently-useless-field")

        strDataPtr = self.dataPtrFromStrPtr(strPtr)
        terminatorPtr = OffsetPtr(strDataPtr, length)
        self.assertEquals(Marshal.ReadByte(terminatorPtr), 0,
                          "string not terminated")
Пример #11
0
    def testZero(self):
        bufferlen = 200
        zerolen = 173

        data = Marshal.AllocHGlobal(bufferlen)
        this = data
        for _ in xrange(bufferlen):
            CPyMarshal.WriteByte(this, 255)
            this = OffsetPtr(this, 1)

        CPyMarshal.Zero(data, zerolen)

        this = data
        for i in xrange(bufferlen):
            actual = CPyMarshal.ReadByte(this)
            expected = (255, 0)[i < zerolen]
            self.assertEquals(
                actual, expected,
                "wrong value at %d (%d, %d)" % (i, actual, expected))
            this = OffsetPtr(this, 1)

        Marshal.FreeHGlobal(data)
Пример #12
0
    def testStoreList(self, mapper, _):
        list_ = [1, 2, 3]
        listPtr = mapper.Store(list_)
        self.assertEquals(id(mapper.Retrieve(listPtr)), id(list_))
        
        typePtr = CPyMarshal.ReadPtrField(listPtr, PyObject, "ob_type")
        self.assertEquals(typePtr, mapper.PyList_Type, "wrong type")

        dataStore = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item")
        for i in range(1, 4):
            self.assertEquals(mapper.Retrieve(CPyMarshal.ReadPtr(dataStore)), i, "contents not stored")
            self.assertEquals(mapper.RefCount(CPyMarshal.ReadPtr(dataStore)), 1, "bad refcount for items")
            dataStore = OffsetPtr(dataStore, CPyMarshal.PtrSize)
Пример #13
0
    def testIC_PyFile_AsFile(self, mapper, addToCleanUp, stderr_writes):
        buflen = len(TEST_TEXT) + 10
        buf = Marshal.AllocHGlobal(buflen)
        
        filePtr = mapper.Store(open(*READ_ARGS))
        
        f = mapper.IC_PyFile_AsFile(filePtr)
        self.assertEquals(stderr_writes, [('Warning: creating unmanaged FILE* from managed stream. Please use ironclad.open with this extension.',), ('\n',)])
        self.assertEquals(Unmanaged.fread(buf, 1, buflen, f), len(TEST_TEXT), "didn't get a real FILE")
        ptr = buf
        for c in TEST_TEXT:
            self.assertEquals(Marshal.ReadByte(ptr), ord(c), "got bad data from FILE")
            ptr = OffsetPtr(ptr, 1)

        Marshal.FreeHGlobal(buf)
Пример #14
0
def MakeItemsTablePtr(items):
    if not items:
        return IntPtr.Zero, lambda: None
    itemtype = items[0].__class__
    typesize = Marshal.SizeOf(itemtype())
    size = typesize * (len(items) + 1)
    
    tablePtr = Marshal.AllocHGlobal(size)
    CPyMarshal.Zero(tablePtr, size)
    for i, item in enumerate(items):
        Marshal.StructureToPtr(item, OffsetPtr(tablePtr, typesize * i), False)

    def dealloc():
        Marshal.DestroyStructure(tablePtr, itemtype)
        Marshal.FreeHGlobal(tablePtr)
    return tablePtr, dealloc
Пример #15
0
    def testPyList_Append(self):
        allocs = []
        deallocs = []
        mapper = PythonMapper(GetAllocatingTestAllocator(allocs, deallocs))
        deallocTypes = CreateTypes(mapper)
        
        del allocs[:]
        listPtr = mapper.PyList_New(0)
        self.assertEquals(allocs, [(listPtr, Marshal.SizeOf(PyListObject))], "bad alloc")

        item1 = object()
        item2 = object()
        itemPtr1 = mapper.Store(item1)
        itemPtr2 = mapper.Store(item2)
        
        self.assertEquals(mapper.PyList_Append(listPtr, itemPtr1), 0, "failed to report success")
        self.assertEquals(len(allocs), 4, "didn't allocate memory for data store (list; item1; item2; data store comes 4th)")

        dataPtrAfterFirstAppend = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item")
        self.assertEquals(allocs[3], (dataPtrAfterFirstAppend, CPyMarshal.PtrSize), "allocated wrong amount of memory")
        self.assertEquals(CPyMarshal.ReadPtr(dataPtrAfterFirstAppend), itemPtr1, "failed to fill memory")
        self.assertEquals(mapper.RefCount(itemPtr1), 2, "failed to incref new contents")
        self.assertEquals(mapper.Retrieve(listPtr), [item1], "retrieved wrong list")
        
        # make refcount 1, to prove that references are not lost when reallocing data
        mapper.DecRef(itemPtr1)

        self.assertEquals(mapper.PyList_Append(listPtr, itemPtr2), 0, "failed to report success")
        self.assertEquals(len(allocs), 5, "didn't allocate memory for new, larger data store")
        self.assertEquals(deallocs, [dataPtrAfterFirstAppend])

        dataPtrAfterSecondAppend = CPyMarshal.ReadPtrField(listPtr, PyListObject, "ob_item")
        self.assertEquals(allocs[4], (dataPtrAfterSecondAppend, (CPyMarshal.PtrSize * 2)), 
                          "allocated wrong amount of memory")
        self.assertEquals(CPyMarshal.ReadPtr(dataPtrAfterSecondAppend), itemPtr1, 
                          "failed to keep reference to first item")
        self.assertEquals(CPyMarshal.ReadPtr(OffsetPtr(dataPtrAfterSecondAppend, CPyMarshal.PtrSize)), itemPtr2, 
                          "failed to keep reference to first item")
        self.assertEquals(mapper.RefCount(itemPtr1), 1, "wrong refcount for item existing only in list")
        self.assertEquals(mapper.RefCount(itemPtr2), 2, "wrong refcount newly-added item")
        self.assertEquals(mapper.Retrieve(listPtr), [item1, item2], "retrieved wrong list")
        
        mapper.Dispose()
        deallocTypes()
Пример #16
0
 def dataPtrFromStrPtr(self, strPtr):
     return OffsetPtr(strPtr, Marshal.OffsetOf(PyStringObject, "ob_sval"))
Пример #17
0
 def ptrFromByteArray(self, bytes):
     testData = Marshal.AllocHGlobal(bytes.Length + 1)
     Marshal.Copy(bytes, 0, testData, bytes.Length)
     Marshal.WriteByte(OffsetPtr(testData, bytes.Length), 0)
     return testData
Пример #18
0
 def WriteBytes(address):
     for a in range(intCount):
         ptr = OffsetPtr(address, a * CPyMarshal.IntSize)
         Marshal.WriteInt32(ptr, TEST_NUMBER)
Пример #19
0
 def TestWroteBytes(address):
     for a in range(intCount):
         ptr = OffsetPtr(address, a * CPyMarshal.IntSize)
         data = Marshal.ReadInt32(ptr)
         if data != TEST_NUMBER:
             raise AssertionError("write failed")