This repository was archived by the owner on Feb 13, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathshared.py
More file actions
142 lines (115 loc) · 4.41 KB
/
shared.py
File metadata and controls
142 lines (115 loc) · 4.41 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# Copyright 2018 The Native Object Protocols Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Example of using libnop from python by wrapping operations in a shared
# library. The shared library is loaded using the ctypes module.
#
from ctypes import *
import sys
import os
# Define ctypes structures that mirror the basic protocol types.
# Three component vector of floats.
class Vec3(Structure):
_fields_ = (('x', c_float), ('y', c_float), ('z', c_float))
def __str__(self):
return '(%.1f, %.1f, %.1f)' % (self.x, self.y, self.z)
# Triangle composed of three Vec3 structures.
class Triangle(Structure):
_fields_ = (('a', Vec3), ('b', Vec3), ('c', Vec3))
def __str__(self):
return 'Triangle{%s, %s, %s}' % (self.a, self.b, self.c)
# Base Polyhedron structure. This carries the size of the Triangle array
# appended to the end of the structure.
class PolyhedronBase(Structure):
_fields_ = (('size', c_size_t),)
# Builds a Polyhedron given either a list of Triangles or a capacity to reserve.
#
# This is equivalent to the following C header struct + dynamic array idiom:
#
# struct Polyhedron {
# size_t size;
# Triangle triangles[1];
# };
#
# Polyhedron* p = malloc(offsetof(Polyhedron, triangles) + reserve * sizeof(Triangle));
#
def Polyhedron(elements=[], reserve=None):
if reserve is None:
reserve = len(elements)
# Triangle array of the required size.
class ArrayType(Array):
_type_ = Triangle
_length_ = reserve
# A subclass of PolyhedronBase with an array of Triangles appended.
class PolyhedronType(PolyhedronBase):
_fields_ = (('triangles', ArrayType),)
def __str__(self):
return 'Polyhedron{' + ', '.join(
[str(self.triangles[i]) for i in range(self.size)]
) + '}'
# Return an initialized instance of the Polyhedron.
return PolyhedronType(reserve, ArrayType(*elements))
def LoadProtocolLibrary():
global ProtocolLibrary
global GetSerializedPolyhedron
global SerializePolyhedron
global DeserializePolyhedron
# Load the shared library.
ProtocolLibrary = cdll.LoadLibrary('out/shared_protocol.so')
# Load the exported API and setup the function pointer types.
GetSerializedPolyhedron = ProtocolLibrary.GetSerializedPolyhedron
GetSerializedPolyhedron.argtypes = (c_void_p, c_size_t)
GetSerializedPolyhedron.restype = c_ssize_t
SerializePolyhedron = ProtocolLibrary.SerializePolyhedron
SerializePolyhedron.argtypes = (POINTER(PolyhedronBase), c_void_p, c_size_t)
SerializePolyhedron.restype = c_ssize_t
DeserializePolyhedron = ProtocolLibrary.DeserializePolyhedron
DeserializePolyhedron.argtypes = (POINTER(PolyhedronBase), c_void_p, c_size_t)
DeserializePolyhedron.restype = c_ssize_t
def main():
LoadProtocolLibrary()
# Create a buffer to hold the serialized payload.
payload_buffer = create_string_buffer(1024)
# Create a Polyhedron and serialize it to the buffer.
polyhedron = Polyhedron(
(
Triangle(Vec3(0, 0, 0), Vec3(1, 1, 1), Vec3(2, 2, 2)),
Triangle(Vec3(3, 3, 3), Vec3(4, 4, 4), Vec3(5, 5, 5)),
Triangle(Vec3(6, 6, 6), Vec3(7, 7, 7), Vec3(8, 8, 8))
)
)
count = SerializePolyhedron(polyhedron, payload_buffer, len(payload_buffer))
if count >= 0:
print count, 'bytes:', payload_buffer[0:count].encode('hex')
else:
print 'Error:', -count
# Create an empty Polyhedron that can hold up to 10 triangles read the payload.
polyhedron = Polyhedron(reserve=10)
count = DeserializePolyhedron(polyhedron, payload_buffer, len(payload_buffer))
if count >= 0:
print polyhedron
else:
print 'Error:', -count
# Get a serialized Polyhedron from the library and then deserialize it.
count = GetSerializedPolyhedron(payload_buffer, len(payload_buffer))
if count < 0:
print 'Error:', -count
return;
count = DeserializePolyhedron(polyhedron, payload_buffer, len(payload_buffer))
if count >= 0:
print polyhedron
else:
print 'Error:', -count
if __name__ == '__main__':
main()