ObjXMPP  Diff

Differences From Artifact [7c662ebfbc]:

To Artifact [af88dd61ac]:


1
2


3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9
10

-
+
+







/*
 * Copyright (c) 2011, 2012, 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
 * Copyright (c) 2011, 2012, 2013, 2016, 2019, 2021,
 *   Jonathan Schleifer <js@nil.im>
 * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
 *
 * https://heap.zone/objxmpp/
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
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
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180

181
182

183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206

207
208

209
210

211
212
213
214
215
216
217
218
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175

176
177

178

179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198

199
200

201
202

203


204

205
206
207
208
209
210
211







-
+
-


-
+








-
+
-










-
+
-






-
+
-













-
+















-
+
-


















-
+

-
+

-
+
-






-
+













-
+

-
+

-
+
-
-
+
-







- (void)requestRoster
{
	XMPPIQ *IQ;
	OFXMLElement *query;

	_rosterRequested = true;

	IQ = [XMPPIQ IQWithType: @"get"
	IQ = [XMPPIQ IQWithType: @"get" ID: [_connection generateStanzaID]];
			     ID: [_connection generateStanzaID]];

	query = [OFXMLElement elementWithName: @"query"
				    namespace: XMPP_NS_ROSTER];
				    namespace: XMPPRosterNS];

	if (_connection.supportsRosterVersioning) {
		OFString *ver =
		    [_dataStorage stringValueForPath: @"roster.ver"];

		if (ver == nil)
			ver = @"";

		[query addAttributeWithName: @"ver"
		[query addAttributeWithName: @"ver" stringValue: ver];
				stringValue: ver];
	}

	[IQ addChild: query];

	[_connection sendIQ: IQ
	     callbackTarget: self
		   selector: @selector(xmpp_handleInitialRosterForConnection:
				IQ:)];
}

- (bool)connection: (XMPPConnection *)connection
- (bool)connection: (XMPPConnection *)connection didReceiveIQ: (XMPPIQ *)IQ
      didReceiveIQ: (XMPPIQ *)IQ
{
	OFXMLElement *rosterElement;
	OFXMLElement *element;
	XMPPRosterItem *rosterItem;
	OFString *origin;

	rosterElement = [IQ elementForName: @"query"
	rosterElement = [IQ elementForName: @"query" namespace: XMPPRosterNS];
				 namespace: XMPP_NS_ROSTER];

	if (rosterElement == nil)
		return false;

	if (![IQ.type isEqual: @"set"])
		return false;

	// Ensure the roster push has been sent by the server
	origin = IQ.from.fullJID;
	if (origin != nil && ![origin isEqual: connection.JID.bareJID])
		return false;

	element = [rosterElement elementForName: @"item"
				      namespace: XMPP_NS_ROSTER];
				      namespace: XMPPRosterNS];

	if (element != nil) {
		rosterItem = [self xmpp_rosterItemWithXMLElement: element];

		[_delegates broadcastSelector: @selector(
						   roster:didReceiveRosterItem:)
				   withObject: self
				   withObject: rosterItem];

		[self xmpp_updateRosterItem: rosterItem];
	}

	if (_connection.supportsRosterVersioning) {
		OFString *ver =
		    [rosterElement attributeForName: @"ver"].stringValue;
		[_dataStorage setStringValue: ver
		[_dataStorage setStringValue: ver forPath: @"roster.ver"];
				     forPath: @"roster.ver"];
		[_dataStorage save];
	}

	[connection sendStanza: [IQ resultIQ]];

	return true;
}

- (void)addRosterItem: (XMPPRosterItem *)rosterItem
{
	[self updateRosterItem: rosterItem];
}

- (void)updateRosterItem: (XMPPRosterItem *)rosterItem
{
	XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
				     ID: [_connection generateStanzaID]];
	OFXMLElement *query = [OFXMLElement elementWithName: @"query"
						  namespace: XMPP_NS_ROSTER];
						  namespace: XMPPRosterNS];
	OFXMLElement *item = [OFXMLElement elementWithName: @"item"
						 namespace: XMPP_NS_ROSTER];
						 namespace: XMPPRosterNS];

	[item addAttributeWithName: @"jid"
	[item addAttributeWithName: @"jid" stringValue: rosterItem.JID.bareJID];
		       stringValue: rosterItem.JID.bareJID];
	if (rosterItem.name != nil)
		[item addAttributeWithName: @"name"
			       stringValue: rosterItem.name];

	for (OFString *group in rosterItem.groups)
		[item addChild: [OFXMLElement elementWithName: @"group"
						    namespace: XMPP_NS_ROSTER
						    namespace: XMPPRosterNS
						  stringValue: group]];

	[query addChild: item];
	[IQ addChild: query];

	[_connection sendStanza: IQ];
}

- (void)deleteRosterItem: (XMPPRosterItem *)rosterItem
{
	XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
				     ID: [_connection generateStanzaID]];
	OFXMLElement *query = [OFXMLElement elementWithName: @"query"
						  namespace: XMPP_NS_ROSTER];
						  namespace: XMPPRosterNS];
	OFXMLElement *item = [OFXMLElement elementWithName: @"item"
						 namespace: XMPP_NS_ROSTER];
						 namespace: XMPPRosterNS];

	[item addAttributeWithName: @"jid"
	[item addAttributeWithName: @"jid" stringValue: rosterItem.JID.bareJID];
		       stringValue: rosterItem.JID.bareJID];
	[item addAttributeWithName: @"subscription"
	[item addAttributeWithName: @"subscription" stringValue: @"remove"];
		       stringValue: @"remove"];

	[query addChild: item];
	[IQ addChild: query];

	[_connection sendStanza: IQ];
}

255
256
257
258
259
260
261
262

263
264
265
266
267

268
269
270
271
272
273
274
275
248
249
250
251
252
253
254

255

256
257
258

259

260
261
262
263
264
265
266







-
+
-



-
+
-







				[item setObject: rosterItem.name
					 forKey: @"name"];

			if ([rosterItem groups] != nil)
				[item setObject: rosterItem.groups
					 forKey: @"groups"];

			[items setObject: item
			[items setObject: item forKey: rosterItem.JID.bareJID];
				  forKey: rosterItem.JID.bareJID];
		} else
			[items removeObjectForKey: rosterItem.JID.bareJID];

		[_dataStorage setDictionary: items
		[_dataStorage setDictionary: items forPath: @"roster.items"];
				    forPath: @"roster.items"];
	}

	if (![rosterItem.subscription isEqual: @"remove"])
		[_rosterItems setObject: rosterItem
				 forKey: rosterItem.JID.bareJID];
	else
		[_rosterItems removeObjectForKey: rosterItem.JID.bareJID];
292
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
283
284
285
286
287
288
289

290

291
292
293
294
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310







-
+
-












-
+







	    ![subscription isEqual: @"both"] &&
	    ![subscription isEqual: @"remove"])
		subscription = @"none";

	rosterItem.subscription = subscription;

	for (OFXMLElement *groupElement in
	    [element elementsForName: @"group"
	    [element elementsForName: @"group" namespace: XMPPRosterNS])
			   namespace: XMPP_NS_ROSTER])
		[groups addObject: groupElement.stringValue];

	if (groups.count > 0)
		rosterItem.groups = groups;

	return rosterItem;
}

- (void)xmpp_handleInitialRosterForConnection: (XMPPConnection *)connection
					   IQ: (XMPPIQ *)IQ
{
	OFXMLElement *rosterElement = [IQ elementForName: @"query"
					       namespace: XMPP_NS_ROSTER];
					       namespace: XMPPRosterNS];

	if (connection.supportsRosterVersioning) {
		if (rosterElement == nil) {
			for (OFDictionary *item in
			    [_dataStorage dictionaryForPath: @"roster.items"]) {
				XMPPRosterItem *rosterItem;
				XMPPJID *JID;
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347

348

349
350
351
352
353
354
355







-
+












-
+
-







	}

	for (OFXMLElement *element in rosterElement.children) {
		void *pool = objc_autoreleasePoolPush();
		XMPPRosterItem *rosterItem;

		if (![element.name isEqual: @"item"] ||
		    ![element.namespace isEqual: XMPP_NS_ROSTER])
		    ![element.namespace isEqual: XMPPRosterNS])
			continue;

		rosterItem = [self xmpp_rosterItemWithXMLElement: element];

		[self xmpp_updateRosterItem: rosterItem];

		objc_autoreleasePoolPop(pool);
	}

	if (connection.supportsRosterVersioning && rosterElement != nil) {
		OFString *ver =
		    [rosterElement attributeForName: @"ver"].stringValue;
		[_dataStorage setStringValue: ver
		[_dataStorage setStringValue: ver forPath: @"roster.ver"];
				     forPath: @"roster.ver"];
		[_dataStorage save];
	}

	[_delegates broadcastSelector: @selector(rosterWasReceived:)
			   withObject: self];
}
@end