Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/type/useful.py: 47%

99 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:25 +0000

1# 

2# This file is part of pyasn1 software. 

3# 

4# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com> 

5# License: http://snmplabs.com/pyasn1/license.html 

6# 

7import datetime 

8 

9from pyasn1 import error 

10from pyasn1.compat import dateandtime 

11from pyasn1.compat import string 

12from pyasn1.type import char 

13from pyasn1.type import tag 

14from pyasn1.type import univ 

15 

16__all__ = ['ObjectDescriptor', 'GeneralizedTime', 'UTCTime'] 

17 

18NoValue = univ.NoValue 

19noValue = univ.noValue 

20 

21 

22class ObjectDescriptor(char.GraphicString): 

23 __doc__ = char.GraphicString.__doc__ 

24 

25 #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects 

26 tagSet = char.GraphicString.tagSet.tagImplicitly( 

27 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 7) 

28 ) 

29 

30 # Optimization for faster codec lookup 

31 typeId = char.GraphicString.getTypeId() 

32 

33 

34class TimeMixIn(object): 

35 

36 _yearsDigits = 4 

37 _hasSubsecond = False 

38 _optionalMinutes = False 

39 _shortTZ = False 

40 

41 class FixedOffset(datetime.tzinfo): 

42 """Fixed offset in minutes east from UTC.""" 

43 

44 # defaulted arguments required 

45 # https: // docs.python.org / 2.3 / lib / datetime - tzinfo.html 

46 def __init__(self, offset=0, name='UTC'): 

47 self.__offset = datetime.timedelta(minutes=offset) 

48 self.__name = name 

49 

50 def utcoffset(self, dt): 

51 return self.__offset 

52 

53 def tzname(self, dt): 

54 return self.__name 

55 

56 def dst(self, dt): 

57 return datetime.timedelta(0) 

58 

59 UTC = FixedOffset() 

60 

61 @property 

62 def asDateTime(self): 

63 """Create :py:class:`datetime.datetime` object from a |ASN.1| object. 

64 

65 Returns 

66 ------- 

67 : 

68 new instance of :py:class:`datetime.datetime` object 

69 """ 

70 text = str(self) 

71 if text.endswith('Z'): 

72 tzinfo = TimeMixIn.UTC 

73 text = text[:-1] 

74 

75 elif '-' in text or '+' in text: 

76 if '+' in text: 

77 text, plusminus, tz = string.partition(text, '+') 

78 else: 

79 text, plusminus, tz = string.partition(text, '-') 

80 

81 if self._shortTZ and len(tz) == 2: 

82 tz += '00' 

83 

84 if len(tz) != 4: 

85 raise error.PyAsn1Error('malformed time zone offset %s' % tz) 

86 

87 try: 

88 minutes = int(tz[:2]) * 60 + int(tz[2:]) 

89 if plusminus == '-': 

90 minutes *= -1 

91 

92 except ValueError: 

93 raise error.PyAsn1Error('unknown time specification %s' % self) 

94 

95 tzinfo = TimeMixIn.FixedOffset(minutes, '?') 

96 

97 else: 

98 tzinfo = None 

99 

100 if '.' in text or ',' in text: 

101 if '.' in text: 

102 text, _, ms = string.partition(text, '.') 

103 else: 

104 text, _, ms = string.partition(text, ',') 

105 

106 try: 

107 ms = int(ms) * 1000 

108 

109 except ValueError: 

110 raise error.PyAsn1Error('bad sub-second time specification %s' % self) 

111 

112 else: 

113 ms = 0 

114 

115 if self._optionalMinutes and len(text) - self._yearsDigits == 6: 

116 text += '0000' 

117 elif len(text) - self._yearsDigits == 8: 

118 text += '00' 

119 

120 try: 

121 dt = dateandtime.strptime(text, self._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S') 

122 

123 except ValueError: 

124 raise error.PyAsn1Error('malformed datetime format %s' % self) 

125 

126 return dt.replace(microsecond=ms, tzinfo=tzinfo) 

127 

128 @classmethod 

129 def fromDateTime(cls, dt): 

130 """Create |ASN.1| object from a :py:class:`datetime.datetime` object. 

131 

132 Parameters 

133 ---------- 

134 dt: :py:class:`datetime.datetime` object 

135 The `datetime.datetime` object to initialize the |ASN.1| object 

136 from 

137 

138 Returns 

139 ------- 

140 : 

141 new instance of |ASN.1| value 

142 """ 

143 text = dt.strftime(cls._yearsDigits == 4 and '%Y%m%d%H%M%S' or '%y%m%d%H%M%S') 

144 if cls._hasSubsecond: 

145 text += '.%d' % (dt.microsecond // 1000) 

146 

147 if dt.utcoffset(): 

148 seconds = dt.utcoffset().seconds 

149 if seconds < 0: 

150 text += '-' 

151 else: 

152 text += '+' 

153 text += '%.2d%.2d' % (seconds // 3600, seconds % 3600) 

154 else: 

155 text += 'Z' 

156 

157 return cls(text) 

158 

159 

160class GeneralizedTime(char.VisibleString, TimeMixIn): 

161 __doc__ = char.VisibleString.__doc__ 

162 

163 #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects 

164 tagSet = char.VisibleString.tagSet.tagImplicitly( 

165 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 24) 

166 ) 

167 

168 # Optimization for faster codec lookup 

169 typeId = char.VideotexString.getTypeId() 

170 

171 _yearsDigits = 4 

172 _hasSubsecond = True 

173 _optionalMinutes = True 

174 _shortTZ = True 

175 

176 

177class UTCTime(char.VisibleString, TimeMixIn): 

178 __doc__ = char.VisibleString.__doc__ 

179 

180 #: Default :py:class:`~pyasn1.type.tag.TagSet` object for |ASN.1| objects 

181 tagSet = char.VisibleString.tagSet.tagImplicitly( 

182 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 23) 

183 ) 

184 

185 # Optimization for faster codec lookup 

186 typeId = char.VideotexString.getTypeId() 

187 

188 _yearsDigits = 2 

189 _hasSubsecond = False 

190 _optionalMinutes = False 

191 _shortTZ = False