1 #!/usr/bin/env python 2 3 """ 4 String objects. 5 6 Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from __builtins__.int import maxint, minint 23 from __builtins__.operator import _negate 24 from __builtins__.sequence import itemaccess 25 import native 26 27 class basestring(itemaccess): 28 29 "The base class for all strings." 30 31 _p = maxint / 32 32 _a = 31 33 34 def __init__(self): 35 36 "Initialise the string." 37 38 # Note the __data__ member. Since strings are either initialised from 39 # literals or converted using routines defined for other types, no form 40 # of actual initialisation is performed here. 41 42 self.__data__ = None 43 44 def __hash__(self): 45 46 "Return a value for hashing purposes." 47 48 result = 0 49 l = self.__len__() 50 i = 0 51 52 while i < l: 53 result = (result * self._a + ord(self.__get_single_item__(i))) % self._p 54 i += 1 55 56 return result 57 58 def _binary_op(self, op, other): 59 60 "Perform 'op' on this int and 'other' if appropriate." 61 62 if isinstance(other, basestring): 63 return op(self.__data__, other.__data__) 64 else: 65 return NotImplemented 66 67 def __iadd__(self, other): 68 69 "Return a string combining this string with 'other'." 70 71 return self._binary_op(native._str_add, other) 72 73 __add__ = __radd__ = __iadd__ 74 75 def __mul__(self, other): pass 76 def __rmul__(self, other): pass 77 def __mod__(self, other): pass 78 def __rmod__(self, other): pass 79 80 def __lt__(self, other): 81 82 "Return whether this string is less than 'other'." 83 84 return self._binary_op(native._str_lt, other) 85 86 def __gt__(self, other): 87 88 "Return whether this string is greater than 'other'." 89 90 return self._binary_op(native._str_gt, other) 91 92 def __le__(self, other): 93 94 "Return whether this string is less than or equal to 'other'." 95 96 return _negate(self.__gt__(other)) 97 98 def __ge__(self, other): 99 100 "Return whether this string is greater than or equal to 'other'." 101 102 return _negate(self.__lt__(other)) 103 104 def __eq__(self, other): 105 106 "Return whether this string is equal to 'other'." 107 108 return self._binary_op(native._str_eq, other) 109 110 def __ne__(self, other): 111 112 "Return whether this string is not equal to 'other'." 113 114 return _negate(self.__eq__(other)) 115 116 def __len__(self): 117 118 "Return the length of this string." 119 120 return native._str_len(self.__data__) 121 122 def __str__(self): 123 124 "Return a string representation." 125 126 return self 127 128 def __repr__(self): 129 130 "Return a program representation." 131 132 # NOTE: To be implemented with proper quoting. 133 b = buffer(['"', self, '"']) 134 return str(b) 135 136 def __bool__(self): 137 return native._str_nonempty(self.__data__) 138 139 def endswith(self, s): pass 140 def find(self, sub, start=None, end=None): pass 141 def index(self, sub, start=None, end=None): pass 142 def join(self, l): pass 143 def lower(self): pass 144 def lstrip(self, chars=None): pass 145 def replace(self, old, new, count=None): pass 146 def rfind(self, sub, start=None, end=None): pass 147 def rsplit(self, sep=None, maxsplit=None): pass 148 def rstrip(self, chars=None): pass 149 def split(self, sep=None, maxsplit=None): pass 150 def splitlines(self, keepends=False): pass 151 def startswith(self, s): pass 152 def strip(self, chars=None): pass 153 def upper(self): pass 154 155 # Special implementation methods. 156 157 def __get_single_item__(self, index): 158 159 "Return the item at the normalised (positive) 'index'." 160 161 self._check_index(index) 162 return native._str_substr(self.__data__, index, 1) 163 164 class string(basestring): 165 pass 166 167 class unicode(basestring): 168 def encode(self, encoding): pass 169 170 def str(obj): 171 172 "Return the string representation of 'obj'." 173 174 # Class attributes of instances provide __str__. 175 176 return obj.__str__() 177 178 # vim: tabstop=4 expandtab shiftwidth=4