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
|
# -*- coding: utf-8 -*-
#
# AWL data offset
#
# Copyright 2012-2016 Michael Buesch <m@bues.ch>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
from __future__ import division, absolute_import, print_function, unicode_literals
from awlsim.common.compat import *
from awlsim.common.datatypehelpers import *
#from awlsim.core.dynattrs cimport * #@cy
from awlsim.core.dynattrs import * #@nocy
from awlsim.core.util import *
class AwlOffset(DynAttrs): #+cdef
"Memory area offset"
dynAttrs = {
# A DB-number for fully qualified access, or None.
"dbNumber" : None,
# A symbolic DB-name for fully qualified access, or None.
"dbName" : None,
# An AwlDataIdentChain, or None.
# Used for fully qualified (DBx.VAR) or named local (#VAR)
# global symbolic ("VAR") accesses.
# For global symbols the chain only has one element.
"identChain" : None,
# A (S)FB-number for multi-instance calls, or None.
"fbNumber" : None,
# Additional sub-offset that is added to this offset.
# Defaults to 0.0
# This is used for arrays and structs.
"subOffset" : lambda self, name: AwlOffset(),
}
def __init__(self, byteOffset=0, bitOffset=0):
self.byteOffset, self.bitOffset =\
byteOffset, bitOffset
def __eq__(self, other): #@nocy
#@cy cdef __eq(self, object other):
return (self is other) or (\
isinstance(other, AwlOffset) and\
self.byteOffset == other.byteOffset and\
self.bitOffset == other.bitOffset and\
super(AwlOffset, self).__eq__(other)\
)
#@cy def __richcmp__(self, object other, int op):
#@cy if op == 2: # __eq__
#@cy return self.__eq(other)
#@cy elif op == 3: # __ne__
#@cy return not self.__eq(other)
#@cy return False
def __ne__(self, other): #@nocy
return not self.__eq__(other) #@nocy
def dup(self):
offset = AwlOffset(self.byteOffset,
self.bitOffset)
offset.dbNumber = self.dbNumber
return offset
@classmethod
def fromPointerValue(cls, value):
return cls((value & 0x0007FFF8) >> 3,
(value & 0x7))
def toPointerValue(self):
return ((self.byteOffset << 3) & 0x0007FFF8) |\
(self.bitOffset & 0x7)
@classmethod
def fromBitOffset(cls, bitOffset):
return cls(bitOffset // 8, bitOffset % 8)
def toBitOffset(self):
return self.byteOffset * 8 + self.bitOffset
def __add__(self, other):
bitOffset = (self.byteOffset + other.byteOffset) * 8 +\
self.bitOffset + other.bitOffset
return AwlOffset(bitOffset // 8, bitOffset % 8)
def __iadd__(self, other):
bitOffset = (self.byteOffset + other.byteOffset) * 8 +\
self.bitOffset + other.bitOffset
self.byteOffset = bitOffset // 8
self.bitOffset = bitOffset % 8
return self
# Round the offset to a multiple of 'byteBase' bytes.
# Returns an AwlOffset.
def roundUp(self, byteBase):
byteOffset = self.byteOffset
if self.bitOffset:
byteOffset += 1
byteOffset = roundUp(byteOffset, byteBase)
return AwlOffset(byteOffset)
def __repr__(self):
prefix = ""
if self.dbNumber is not None:
prefix = "DB%d" % self.dbNumber
if self.dbName is not None:
prefix = '"%s"' % self.dbName
if self.identChain is not None:
if prefix:
return prefix + "." + self.identChain.getString()
return "#" + self.identChain.getString()
else:
if prefix:
prefix = prefix + ".DBX "
return "%s%d.%d" % (prefix,
self.byteOffset,
self.bitOffset)
|