CFString.py revision 579a296e7566b7b6d24b51e383bca1fe1e62086f
1579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 2579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLLDB AppKit formatters 3579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 4579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granatapart of The LLVM Compiler Infrastructure 5579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataThis file is distributed under the University of Illinois Open Source 6579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLicense. See LICENSE.TXT for details. 7579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 8b370df27c76fd875f3312be487868528121a4838Enrico Granata# synthetic children and summary provider for CFString 9b370df27c76fd875f3312be487868528121a4838Enrico Granata# (and related NSString class) 10b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb 1183410e5e9e040ea5c6691f933aa9a6c4dcea4d8bEnrico Granataimport objc_runtime 12b370df27c76fd875f3312be487868528121a4838Enrico Granata 13b370df27c76fd875f3312be487868528121a4838Enrico Granatadef CFString_SummaryProvider (valobj,dict): 14b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = CFStringSynthProvider(valobj,dict); 15b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider.invalid == False: 16579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata try: 17579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = provider.get_child_at_index(provider.get_child_index("content")).GetSummary(); 18579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata except: 19579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = None 20579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == None: 21579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSString>' 22579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '@'+summary 23b370df27c76fd875f3312be487868528121a4838Enrico Granata return '' 24b370df27c76fd875f3312be487868528121a4838Enrico Granata 25b370df27c76fd875f3312be487868528121a4838Enrico Granatadef CFAttributedString_SummaryProvider (valobj,dict): 26b370df27c76fd875f3312be487868528121a4838Enrico Granata offset = valobj.GetTarget().GetProcess().GetAddressByteSize() 27b370df27c76fd875f3312be487868528121a4838Enrico Granata pointee = valobj.GetValueAsUnsigned(0) 28579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSAttributedString>' 29b370df27c76fd875f3312be487868528121a4838Enrico Granata if pointee != None and pointee != 0: 30b370df27c76fd875f3312be487868528121a4838Enrico Granata pointee = pointee + offset 31b370df27c76fd875f3312be487868528121a4838Enrico Granata child_ptr = valobj.CreateValueFromAddress("string_ptr",pointee,valobj.GetType()) 32b370df27c76fd875f3312be487868528121a4838Enrico Granata child = child_ptr.CreateValueFromAddress("string_data",child_ptr.GetValueAsUnsigned(),valobj.GetType()).AddressOf() 33b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = CFStringSynthProvider(child,dict); 34b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider.invalid == False: 35b370df27c76fd875f3312be487868528121a4838Enrico Granata try: 36b370df27c76fd875f3312be487868528121a4838Enrico Granata summary = provider.get_child_at_index(provider.get_child_index("content")).GetSummary(); 37b370df27c76fd875f3312be487868528121a4838Enrico Granata except: 38579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSAttributedString>' 39b370df27c76fd875f3312be487868528121a4838Enrico Granata if summary == None: 40579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSAttributedString>' 41b370df27c76fd875f3312be487868528121a4838Enrico Granata return '@'+summary 42b370df27c76fd875f3312be487868528121a4838Enrico Granata 43b370df27c76fd875f3312be487868528121a4838Enrico Granata 44b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict): 45b370df27c76fd875f3312be487868528121a4838Enrico Granata debugger.HandleCommand("type summary add -F CFString.CFString_SummaryProvider NSString CFStringRef CFMutableStringRef") 46b370df27c76fd875f3312be487868528121a4838Enrico Granata debugger.HandleCommand("type summary add -F CFString.CFAttributedString_SummaryProvider NSAttributedString") 47b370df27c76fd875f3312be487868528121a4838Enrico Granata 48b370df27c76fd875f3312be487868528121a4838Enrico Granataclass CFStringSynthProvider: 49b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,valobj,dict): 50b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 51b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 52b370df27c76fd875f3312be487868528121a4838Enrico Granata 53b370df27c76fd875f3312be487868528121a4838Enrico Granata # children other than "content" are for debugging only and must not be used in production code 54b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 55b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.invalid: 56b370df27c76fd875f3312be487868528121a4838Enrico Granata return 0; 57b370df27c76fd875f3312be487868528121a4838Enrico Granata return 6; 58b370df27c76fd875f3312be487868528121a4838Enrico Granata 59b370df27c76fd875f3312be487868528121a4838Enrico Granata def read_unicode(self, pointer): 60b370df27c76fd875f3312be487868528121a4838Enrico Granata process = self.valobj.GetTarget().GetProcess() 61b370df27c76fd875f3312be487868528121a4838Enrico Granata error = lldb.SBError() 62b370df27c76fd875f3312be487868528121a4838Enrico Granata pystr = u'' 63b370df27c76fd875f3312be487868528121a4838Enrico Granata # cannot do the read at once because the length value has 64b370df27c76fd875f3312be487868528121a4838Enrico Granata # a weird encoding. better play it safe here 65b370df27c76fd875f3312be487868528121a4838Enrico Granata while True: 66b370df27c76fd875f3312be487868528121a4838Enrico Granata content = process.ReadMemory(pointer, 2, error) 67b370df27c76fd875f3312be487868528121a4838Enrico Granata new_bytes = bytearray(content) 68b370df27c76fd875f3312be487868528121a4838Enrico Granata b0 = new_bytes[0] 69b370df27c76fd875f3312be487868528121a4838Enrico Granata b1 = new_bytes[1] 70b370df27c76fd875f3312be487868528121a4838Enrico Granata pointer = pointer + 2 71b370df27c76fd875f3312be487868528121a4838Enrico Granata if b0 == 0 and b1 == 0: 72b370df27c76fd875f3312be487868528121a4838Enrico Granata break 73b370df27c76fd875f3312be487868528121a4838Enrico Granata # rearrange bytes depending on endianness 74b370df27c76fd875f3312be487868528121a4838Enrico Granata # (do we really need this or is Cocoa going to 75b370df27c76fd875f3312be487868528121a4838Enrico Granata # use Windows-compatible little-endian even 76b370df27c76fd875f3312be487868528121a4838Enrico Granata # if the target is big endian?) 77b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_little: 78b370df27c76fd875f3312be487868528121a4838Enrico Granata value = b1 * 256 + b0 79b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 80b370df27c76fd875f3312be487868528121a4838Enrico Granata value = b0 * 256 + b1 81b370df27c76fd875f3312be487868528121a4838Enrico Granata pystr = pystr + unichr(value) 82b370df27c76fd875f3312be487868528121a4838Enrico Granata return pystr 83b370df27c76fd875f3312be487868528121a4838Enrico Granata 84b370df27c76fd875f3312be487868528121a4838Enrico Granata # handle the special case strings 85b370df27c76fd875f3312be487868528121a4838Enrico Granata # only use the custom code for the tested LP64 case 86b370df27c76fd875f3312be487868528121a4838Enrico Granata def handle_special(self): 871328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata if self.is_64_bit == False: 88b370df27c76fd875f3312be487868528121a4838Enrico Granata # for 32bit targets, use safe ObjC code 89b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_unicode_string_safe() 90b370df27c76fd875f3312be487868528121a4838Enrico Granata offset = 12 91b370df27c76fd875f3312be487868528121a4838Enrico Granata pointer = self.valobj.GetValueAsUnsigned(0) + offset 92b370df27c76fd875f3312be487868528121a4838Enrico Granata pystr = self.read_unicode(pointer) 93b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("content", 94b370df27c76fd875f3312be487868528121a4838Enrico Granata "(char*)\"" + pystr.encode('utf-8') + "\"") 95b370df27c76fd875f3312be487868528121a4838Enrico Granata 96b370df27c76fd875f3312be487868528121a4838Enrico Granata # last resort call, use ObjC code to read; the final aim is to 97b370df27c76fd875f3312be487868528121a4838Enrico Granata # be able to strip this call away entirely and only do the read 98b370df27c76fd875f3312be487868528121a4838Enrico Granata # ourselves 99b370df27c76fd875f3312be487868528121a4838Enrico Granata def handle_unicode_string_safe(self): 100b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("content", 101b370df27c76fd875f3312be487868528121a4838Enrico Granata "(char*)\"" + self.valobj.GetObjectDescription() + "\""); 102b370df27c76fd875f3312be487868528121a4838Enrico Granata 103b370df27c76fd875f3312be487868528121a4838Enrico Granata def handle_unicode_string(self): 104b370df27c76fd875f3312be487868528121a4838Enrico Granata # step 1: find offset 105b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.inline: 106b370df27c76fd875f3312be487868528121a4838Enrico Granata pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base(); 107b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.explicit == False: 108b370df27c76fd875f3312be487868528121a4838Enrico Granata # untested, use the safe code path 109b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_unicode_string_safe(); 110b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 1113dcbb2336d4a7b7162aab4719c5f3fff1d1b2355Enrico Granata # a full pointer is skipped here before getting to the live data 112f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pointer = pointer + self.pointer_size 113b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 114b370df27c76fd875f3312be487868528121a4838Enrico Granata pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base(); 115b370df27c76fd875f3312be487868528121a4838Enrico Granata # read 8 bytes here and make an address out of them 116b370df27c76fd875f3312be487868528121a4838Enrico Granata try: 117b370df27c76fd875f3312be487868528121a4838Enrico Granata vopointer = self.valobj.CreateChildAtOffset("dummy", 118b370df27c76fd875f3312be487868528121a4838Enrico Granata pointer,self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()); 119b370df27c76fd875f3312be487868528121a4838Enrico Granata pointer = vopointer.GetValueAsUnsigned(0) 120b370df27c76fd875f3312be487868528121a4838Enrico Granata except: 121b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("content", 122b370df27c76fd875f3312be487868528121a4838Enrico Granata '(char*)"@\"invalid NSString\""') 123b370df27c76fd875f3312be487868528121a4838Enrico Granata # step 2: read Unicode data at pointer 124b370df27c76fd875f3312be487868528121a4838Enrico Granata pystr = self.read_unicode(pointer) 125b370df27c76fd875f3312be487868528121a4838Enrico Granata # step 3: return it 126b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("content", 127b370df27c76fd875f3312be487868528121a4838Enrico Granata "(char*)\"" + pystr.encode('utf-8') + "\"") 128b370df27c76fd875f3312be487868528121a4838Enrico Granata 129b370df27c76fd875f3312be487868528121a4838Enrico Granata def handle_inline_explicit(self): 130f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata offset = 3*self.pointer_size 131b370df27c76fd875f3312be487868528121a4838Enrico Granata offset = offset + self.valobj.GetValueAsUnsigned(0) 132b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("content", 133b370df27c76fd875f3312be487868528121a4838Enrico Granata "(char*)(" + str(offset) + ")") 134b370df27c76fd875f3312be487868528121a4838Enrico Granata 135b370df27c76fd875f3312be487868528121a4838Enrico Granata def handle_mutable_string(self): 136f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata offset = 2 * self.pointer_size 137b370df27c76fd875f3312be487868528121a4838Enrico Granata data = self.valobj.CreateChildAtOffset("content", 138b370df27c76fd875f3312be487868528121a4838Enrico Granata offset, self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()); 139b370df27c76fd875f3312be487868528121a4838Enrico Granata data_value = data.GetValueAsUnsigned(0) 140b370df27c76fd875f3312be487868528121a4838Enrico Granata data_value = data_value + 1 141b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("content", "(char*)(" + str(data_value) + ")") 142b370df27c76fd875f3312be487868528121a4838Enrico Granata 143b370df27c76fd875f3312be487868528121a4838Enrico Granata def handle_UTF8_inline(self): 144b370df27c76fd875f3312be487868528121a4838Enrico Granata offset = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base(); 145b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.explicit == False: 146b370df27c76fd875f3312be487868528121a4838Enrico Granata offset = offset + 1; 147b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromAddress("content", 148b370df27c76fd875f3312be487868528121a4838Enrico Granata offset, self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)).AddressOf(); 149b370df27c76fd875f3312be487868528121a4838Enrico Granata 150b370df27c76fd875f3312be487868528121a4838Enrico Granata def handle_UTF8_not_inline(self): 151b370df27c76fd875f3312be487868528121a4838Enrico Granata offset = self.size_of_cfruntime_base(); 152b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateChildAtOffset("content", 153b370df27c76fd875f3312be487868528121a4838Enrico Granata offset,self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()); 154b370df27c76fd875f3312be487868528121a4838Enrico Granata 155b370df27c76fd875f3312be487868528121a4838Enrico Granata def get_child_at_index(self,index): 156b370df27c76fd875f3312be487868528121a4838Enrico Granata if index == 0: 157b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("mutable", 158b370df27c76fd875f3312be487868528121a4838Enrico Granata str(int(self.mutable))); 159b370df27c76fd875f3312be487868528121a4838Enrico Granata if index == 1: 160b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("inline", 161b370df27c76fd875f3312be487868528121a4838Enrico Granata str(int(self.inline))); 162b370df27c76fd875f3312be487868528121a4838Enrico Granata if index == 2: 163b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("explicit", 164b370df27c76fd875f3312be487868528121a4838Enrico Granata str(int(self.explicit))); 165b370df27c76fd875f3312be487868528121a4838Enrico Granata if index == 3: 166b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("unicode", 167b370df27c76fd875f3312be487868528121a4838Enrico Granata str(int(self.unicode))); 168b370df27c76fd875f3312be487868528121a4838Enrico Granata if index == 4: 169b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valobj.CreateValueFromExpression("special", 170b370df27c76fd875f3312be487868528121a4838Enrico Granata str(int(self.special))); 171b370df27c76fd875f3312be487868528121a4838Enrico Granata if index == 5: 172b370df27c76fd875f3312be487868528121a4838Enrico Granata # we are handling the several possible combinations of flags. 173b370df27c76fd875f3312be487868528121a4838Enrico Granata # for each known combination we have a function that knows how to 174b370df27c76fd875f3312be487868528121a4838Enrico Granata # go fetch the data from memory instead of running code. if a string is not 175b370df27c76fd875f3312be487868528121a4838Enrico Granata # correctly displayed, one should start by finding a combination of flags that 176b370df27c76fd875f3312be487868528121a4838Enrico Granata # makes it different from these known cases, and provide a new reader function 177b370df27c76fd875f3312be487868528121a4838Enrico Granata # if this is not possible, a new flag might have to be made up (like the "special" flag 178b370df27c76fd875f3312be487868528121a4838Enrico Granata # below, which is not a real flag in CFString), or alternatively one might need to use 179b370df27c76fd875f3312be487868528121a4838Enrico Granata # the ObjC runtime helper to detect the new class and deal with it accordingly 180b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.mutable == True: 181b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_mutable_string() 182b370df27c76fd875f3312be487868528121a4838Enrico Granata elif self.inline == True and self.explicit == True and \ 183b370df27c76fd875f3312be487868528121a4838Enrico Granata self.unicode == False and self.special == False and \ 184b370df27c76fd875f3312be487868528121a4838Enrico Granata self.mutable == False: 185b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_inline_explicit() 186b370df27c76fd875f3312be487868528121a4838Enrico Granata elif self.unicode == True: 187b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_unicode_string(); 188b370df27c76fd875f3312be487868528121a4838Enrico Granata elif self.special == True: 189b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_special(); 190b370df27c76fd875f3312be487868528121a4838Enrico Granata elif self.inline == True: 191b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_UTF8_inline(); 192b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 193b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.handle_UTF8_not_inline(); 194b370df27c76fd875f3312be487868528121a4838Enrico Granata 195b370df27c76fd875f3312be487868528121a4838Enrico Granata def get_child_index(self,name): 196b370df27c76fd875f3312be487868528121a4838Enrico Granata if name == "content": 197b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.num_children() - 1; 198b370df27c76fd875f3312be487868528121a4838Enrico Granata if name == "mutable": 199b370df27c76fd875f3312be487868528121a4838Enrico Granata return 0; 200b370df27c76fd875f3312be487868528121a4838Enrico Granata if name == "inline": 201b370df27c76fd875f3312be487868528121a4838Enrico Granata return 1; 202b370df27c76fd875f3312be487868528121a4838Enrico Granata if name == "explicit": 203b370df27c76fd875f3312be487868528121a4838Enrico Granata return 2; 204b370df27c76fd875f3312be487868528121a4838Enrico Granata if name == "unicode": 205b370df27c76fd875f3312be487868528121a4838Enrico Granata return 3; 206b370df27c76fd875f3312be487868528121a4838Enrico Granata if name == "special": 207b370df27c76fd875f3312be487868528121a4838Enrico Granata return 4; 208b370df27c76fd875f3312be487868528121a4838Enrico Granata 209b370df27c76fd875f3312be487868528121a4838Enrico Granata # CFRuntimeBase is defined as having an additional 210b370df27c76fd875f3312be487868528121a4838Enrico Granata # 4 bytes (padding?) on LP64 architectures 211b370df27c76fd875f3312be487868528121a4838Enrico Granata # to get its size we add up sizeof(pointer)+4 212b370df27c76fd875f3312be487868528121a4838Enrico Granata # and then add 4 more bytes if we are on a 64bit system 213b370df27c76fd875f3312be487868528121a4838Enrico Granata def size_of_cfruntime_base(self): 214f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self.pointer_size+4+(4 if self.is_64_bit else 0) 215b370df27c76fd875f3312be487868528121a4838Enrico Granata 216b370df27c76fd875f3312be487868528121a4838Enrico Granata # the info bits are part of the CFRuntimeBase structure 217b370df27c76fd875f3312be487868528121a4838Enrico Granata # to get at them we have to skip a uintptr_t and then get 218b370df27c76fd875f3312be487868528121a4838Enrico Granata # at the least-significant byte of a 4 byte array. If we are 219b370df27c76fd875f3312be487868528121a4838Enrico Granata # on big-endian this means going to byte 3, if we are on 220b370df27c76fd875f3312be487868528121a4838Enrico Granata # little endian (OSX & iOS), this means reading byte 0 221b370df27c76fd875f3312be487868528121a4838Enrico Granata def offset_of_info_bits(self): 222f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata offset = self.pointer_size 223b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_little == False: 224b370df27c76fd875f3312be487868528121a4838Enrico Granata offset = offset + 3; 225b370df27c76fd875f3312be487868528121a4838Enrico Granata return offset; 226b370df27c76fd875f3312be487868528121a4838Enrico Granata 227b370df27c76fd875f3312be487868528121a4838Enrico Granata def read_info_bits(self): 228b370df27c76fd875f3312be487868528121a4838Enrico Granata cfinfo = self.valobj.CreateChildAtOffset("cfinfo", 229b370df27c76fd875f3312be487868528121a4838Enrico Granata self.offset_of_info_bits(), 230b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)); 231b370df27c76fd875f3312be487868528121a4838Enrico Granata cfinfo.SetFormat(11) 232b370df27c76fd875f3312be487868528121a4838Enrico Granata info = cfinfo.GetValue(); 233b370df27c76fd875f3312be487868528121a4838Enrico Granata if info != None: 234b370df27c76fd875f3312be487868528121a4838Enrico Granata self.invalid = False; 235b370df27c76fd875f3312be487868528121a4838Enrico Granata return int(info,0); 236b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 237b370df27c76fd875f3312be487868528121a4838Enrico Granata self.invalid = True; 238b370df27c76fd875f3312be487868528121a4838Enrico Granata return None; 239b370df27c76fd875f3312be487868528121a4838Enrico Granata 240b370df27c76fd875f3312be487868528121a4838Enrico Granata # calculating internal flag bits of the CFString object 241b370df27c76fd875f3312be487868528121a4838Enrico Granata # this stuff is defined and discussed in CFString.c 242b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_mutable(self): 243b370df27c76fd875f3312be487868528121a4838Enrico Granata return (self.info_bits & 1) == 1; 244b370df27c76fd875f3312be487868528121a4838Enrico Granata 245b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_inline(self): 246b370df27c76fd875f3312be487868528121a4838Enrico Granata return (self.info_bits & 0x60) == 0; 247b370df27c76fd875f3312be487868528121a4838Enrico Granata 248b370df27c76fd875f3312be487868528121a4838Enrico Granata # this flag's name is ambiguous, it turns out 249b370df27c76fd875f3312be487868528121a4838Enrico Granata # we must skip a length byte to get at the data 250b370df27c76fd875f3312be487868528121a4838Enrico Granata # when this flag is False 251b370df27c76fd875f3312be487868528121a4838Enrico Granata def has_explicit_length(self): 252b370df27c76fd875f3312be487868528121a4838Enrico Granata return (self.info_bits & (1 | 4)) != 4; 253b370df27c76fd875f3312be487868528121a4838Enrico Granata 254b370df27c76fd875f3312be487868528121a4838Enrico Granata # probably a subclass of NSString. obtained this from [str pathExtension] 255b370df27c76fd875f3312be487868528121a4838Enrico Granata # here info_bits = 0 and Unicode data at the start of the padding word 256b370df27c76fd875f3312be487868528121a4838Enrico Granata # in the long run using the isa value might be safer as a way to identify this 257b370df27c76fd875f3312be487868528121a4838Enrico Granata # instead of reading the info_bits 258b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_special_case(self): 259b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.info_bits == 0; 260b370df27c76fd875f3312be487868528121a4838Enrico Granata 261b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_unicode(self): 262b370df27c76fd875f3312be487868528121a4838Enrico Granata return (self.info_bits & 0x10) == 0x10; 263b370df27c76fd875f3312be487868528121a4838Enrico Granata 264b370df27c76fd875f3312be487868528121a4838Enrico Granata # preparing ourselves to read into memory 265b370df27c76fd875f3312be487868528121a4838Enrico Granata # by adjusting architecture-specific info 266b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 267f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() 268f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.is_64_bit = self.pointer_size == 8 269f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.is_little = self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle 270b370df27c76fd875f3312be487868528121a4838Enrico Granata 271b370df27c76fd875f3312be487868528121a4838Enrico Granata # reading info bits out of the CFString and computing 272b370df27c76fd875f3312be487868528121a4838Enrico Granata # useful values to get at the real data 273b370df27c76fd875f3312be487868528121a4838Enrico Granata def compute_flags(self): 274b370df27c76fd875f3312be487868528121a4838Enrico Granata self.info_bits = self.read_info_bits(); 275b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.info_bits == None: 276b370df27c76fd875f3312be487868528121a4838Enrico Granata return; 277b370df27c76fd875f3312be487868528121a4838Enrico Granata self.mutable = self.is_mutable(); 278b370df27c76fd875f3312be487868528121a4838Enrico Granata self.inline = self.is_inline(); 279b370df27c76fd875f3312be487868528121a4838Enrico Granata self.explicit = self.has_explicit_length(); 280b370df27c76fd875f3312be487868528121a4838Enrico Granata self.unicode = self.is_unicode(); 281b370df27c76fd875f3312be487868528121a4838Enrico Granata self.special = self.is_special_case(); 282b370df27c76fd875f3312be487868528121a4838Enrico Granata 283b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 284b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 285b370df27c76fd875f3312be487868528121a4838Enrico Granata self.compute_flags();