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();