1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2001
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsInterfaceHashtable.h"
39 #include "nsHashKeys.h"
40 #include "nsISchemaLoader.h"
41 #include "nsDefaultSOAPEncoder.h"
42 #include "nsSOAPUtils.h"
43 #include "nsSOAPParameter.h"
44 #include "nsISOAPAttachments.h"
45 #include "nsXPIDLString.h"
46 #include "nsIDOMDocument.h"
47 #include "nsIDOMText.h"
49 #include "nsISchema.h"
50 #include "nsIComponentManager.h"
51 #include "nsIServiceManager.h"
53 #include "nsISupportsPrimitives.h"
54 #include "nsIDOMParser.h"
55 #include "nsSOAPUtils.h"
56 #include "nsISOAPEncoding.h"
57 #include "nsISOAPEncoder.h"
58 #include "nsISOAPDecoder.h"
59 #include "nsISOAPMessage.h"
60 #include "nsSOAPException.h"
65 #include "nsReadableUtils.h"
66 #include "nsIDOMNamedNodeMap.h"
67 #include "nsIDOMAttr.h"
68 #include "nsPrintfCString.h"
69 #include "nsISOAPPropertyBagMutator.h"
70 #include "nsIProperty.h"
71 #include "nsIPropertyBag.h"
72 #include "nsSupportsArray.h"
75 #define MAX_ARRAY_DIMENSIONS 100
77 class nsSOAPEncoderStub
: public nsISOAPEncoder
,
83 PRUint16 mSOAPVersion
;
86 NS_IMPL_ISUPPORTS2(nsSOAPEncoderStub
, nsISOAPEncoder
, nsISOAPDecoder
)
89 // Macros to declare and implement the default encoder classes
92 #define DECLARE_ENCODER(name) \
93 class ns##name##Encoder : public nsSOAPEncoderStub \
96 ns##name##Encoder(); \
97 ns##name##Encoder(PRUint16 aSOAPVersion); \
98 virtual ~ns##name##Encoder(); \
99 NS_DECL_NSISOAPENCODER \
100 NS_DECL_NSISOAPDECODER \
102 ns##name##Encoder::ns##name##Encoder(PRUint16 aSOAPVersion) {mSOAPVersion=aSOAPVersion;} \
103 ns##name##Encoder::~ns##name##Encoder() {}
105 // All encoders must be first declared and then registered.
106 DECLARE_ENCODER(Default
)
107 DECLARE_ENCODER(AnyType
)
108 DECLARE_ENCODER(AnySimpleType
)
109 DECLARE_ENCODER(Array
)
110 DECLARE_ENCODER(Struct
)
111 DECLARE_ENCODER(String
)
112 DECLARE_ENCODER(Boolean
)
113 DECLARE_ENCODER(Double
)
114 DECLARE_ENCODER(Float
)
115 DECLARE_ENCODER(Long
)
117 DECLARE_ENCODER(Short
)
118 DECLARE_ENCODER(Byte
)
119 DECLARE_ENCODER(UnsignedLong
)
120 DECLARE_ENCODER(UnsignedInt
)
121 DECLARE_ENCODER(UnsignedShort
)
122 DECLARE_ENCODER(UnsignedByte
)
123 DECLARE_ENCODER(Base64Binary
)
126 * This now separates the version with respect to the SOAP specification from the version
127 * with respect to the schema version (using the same constants for both). This permits
128 * a user of a SOAP 1.1 or 1.2 encoding to choose which encoding to encode to.
130 #define REGISTER_ENCODER(name,type,uri) \
132 ns##name##Encoder *handler = new ns##name##Encoder(version); \
133 SOAPEncodingKey(uri, gSOAPStrings->k##name##type##Type, encodingKey); \
134 SetEncoder(encodingKey, handler); \
135 SetDecoder(encodingKey, handler); \
138 #define REGISTER_SCHEMA_ENCODER(name) REGISTER_ENCODER(name,Schema,gSOAPStrings->kXSURI)
139 #define REGISTER_SOAP_ENCODER(name) REGISTER_ENCODER(name,SOAP,gSOAPStrings->kSOAPEncURI)
141 #define REGISTER_ENCODERS \
143 nsDefaultEncoder *handler = new nsDefaultEncoder(version); \
144 SetDefaultEncoder(handler); \
145 SetDefaultDecoder(handler); \
147 nsAutoString encodingKey; \
148 REGISTER_SCHEMA_ENCODER(AnyType) \
149 REGISTER_SCHEMA_ENCODER(AnySimpleType) \
150 REGISTER_SOAP_ENCODER(Array) \
151 REGISTER_SOAP_ENCODER(Struct) \
152 REGISTER_SCHEMA_ENCODER(String) \
153 REGISTER_SCHEMA_ENCODER(Boolean) \
154 REGISTER_SCHEMA_ENCODER(Double) \
155 REGISTER_SCHEMA_ENCODER(Float) \
156 REGISTER_SCHEMA_ENCODER(Long) \
157 REGISTER_SCHEMA_ENCODER(Int) \
158 REGISTER_SCHEMA_ENCODER(Short) \
159 REGISTER_SCHEMA_ENCODER(Byte) \
160 REGISTER_SCHEMA_ENCODER(UnsignedLong) \
161 REGISTER_SCHEMA_ENCODER(UnsignedInt) \
162 REGISTER_SCHEMA_ENCODER(UnsignedShort) \
163 REGISTER_SCHEMA_ENCODER(UnsignedByte) \
164 REGISTER_SCHEMA_ENCODER(Base64Binary)
167 // Default SOAP Encodings
170 NS_IMPL_ADDREF(nsDefaultSOAPEncoding_1_1
)
171 NS_IMPL_RELEASE(nsDefaultSOAPEncoding_1_1
)
173 nsDefaultSOAPEncoding_1_1::nsDefaultSOAPEncoding_1_1()
174 : nsSOAPEncoding(gSOAPStrings
->kSOAPEncURI11
, nsnull
, nsnull
)
176 PRUint16 version
= nsISOAPMessage::VERSION_1_1
;
178 MapSchemaURI(gSOAPStrings
->kXSURI1999
,gSOAPStrings
->kXSURI
,PR_TRUE
,&result
);
179 MapSchemaURI(gSOAPStrings
->kXSIURI1999
,gSOAPStrings
->kXSIURI
,PR_TRUE
,&result
);
180 MapSchemaURI(gSOAPStrings
->kSOAPEncURI11
,gSOAPStrings
->kSOAPEncURI
,PR_TRUE
,&result
);
184 NS_IMPL_ADDREF(nsDefaultSOAPEncoding_1_2
)
185 NS_IMPL_RELEASE(nsDefaultSOAPEncoding_1_2
)
187 nsDefaultSOAPEncoding_1_2::nsDefaultSOAPEncoding_1_2()
188 : nsSOAPEncoding(gSOAPStrings
->kSOAPEncURI
, nsnull
, nsnull
)
190 PRUint16 version
= nsISOAPMessage::VERSION_1_2
;
192 MapSchemaURI(gSOAPStrings
->kXSURI1999
,gSOAPStrings
->kXSURI
,PR_FALSE
,&result
);
193 MapSchemaURI(gSOAPStrings
->kXSIURI1999
,gSOAPStrings
->kXSIURI
,PR_FALSE
,&result
);
194 MapSchemaURI(gSOAPStrings
->kSOAPEncURI11
,gSOAPStrings
->kSOAPEncURI
,PR_FALSE
,&result
);
199 // Default Encoders -- static helper functions intermixed
202 // Getting the immediate supertype of any type
203 static nsresult
GetSupertype(nsISOAPEncoding
* aEncoding
,
204 nsISchemaType
* aType
,
205 nsISchemaType
** aResult
)
208 nsresult rc
= aType
->GetSchemaType(&typevalue
);
209 NS_ENSURE_SUCCESS(rc
, rc
);
211 nsCOMPtr
<nsISchemaType
> base
;
214 case nsISchemaType::SCHEMA_TYPE_COMPLEX
:
216 nsCOMPtr
<nsISchemaComplexType
> type
=
217 do_QueryInterface(aType
);
218 rc
= type
->GetBaseType(getter_AddRefs(base
));
219 NS_ENSURE_SUCCESS(rc
, rc
);
223 case nsISchemaType::SCHEMA_TYPE_SIMPLE
:
225 nsCOMPtr
<nsISchemaSimpleType
> type
=
226 do_QueryInterface(aType
);
227 PRUint16 simpletypevalue
;
228 rc
= type
->GetSimpleType(&simpletypevalue
);
229 NS_ENSURE_SUCCESS(rc
, rc
);
231 switch (simpletypevalue
) {
232 // Ultimately, this is wrong because in XML types are value spaces
233 // We have not handled unions and lists.
234 // A union might be considered a supertype of anything it joins
235 // but it is the supertype of all types with value spaces it includes.
236 // SOAP is an attempt to treat XML types as though they were
237 // data types, which are governed by labels instead of value spaces.
238 // So two unrelated values may coexist, but we will disallow it
239 // because the caller probably wants type guarantees, not value
241 case nsISchemaSimpleType::SIMPLE_TYPE_RESTRICTION
:
243 nsCOMPtr
<nsISchemaRestrictionType
> simpletype
=
244 do_QueryInterface(type
);
245 nsCOMPtr
<nsISchemaSimpleType
> simplebasetype
;
246 rc
= simpletype
->GetBaseType(getter_AddRefs(simplebasetype
));
247 NS_ENSURE_SUCCESS(rc
, rc
);
249 base
= simplebasetype
;
252 case nsISchemaSimpleType::SIMPLE_TYPE_BUILTIN
:
254 nsCOMPtr
<nsISchemaBuiltinType
> builtintype
=
255 do_QueryInterface(type
);
256 PRUint16 builtintypevalue
;
257 rc
= builtintype
->GetBuiltinType(&builtintypevalue
);
258 NS_ENSURE_SUCCESS(rc
, rc
);
260 switch(builtintypevalue
) {
261 case nsISchemaBuiltinType::BUILTIN_TYPE_ANYTYPE
: // Root of all types
264 case nsISchemaBuiltinType::BUILTIN_TYPE_STRING
:
265 // name = kAnySimpleTypeSchemaType;
266 name
= gSOAPStrings
->kAnyTypeSchemaType
;
268 case nsISchemaBuiltinType::BUILTIN_TYPE_NORMALIZED_STRING
:
269 name
= gSOAPStrings
->kStringSchemaType
;
271 case nsISchemaBuiltinType::BUILTIN_TYPE_TOKEN
:
272 name
= gSOAPStrings
->kNormalizedStringSchemaType
;
274 case nsISchemaBuiltinType::BUILTIN_TYPE_BYTE
:
275 name
= gSOAPStrings
->kShortSchemaType
;
277 case nsISchemaBuiltinType::BUILTIN_TYPE_UNSIGNEDBYTE
:
278 name
= gSOAPStrings
->kUnsignedShortSchemaType
;
280 case nsISchemaBuiltinType::BUILTIN_TYPE_BASE64BINARY
:
281 // name = kAnySimpleTypeSchemaType;
282 name
= gSOAPStrings
->kAnyTypeSchemaType
;
284 case nsISchemaBuiltinType::BUILTIN_TYPE_HEXBINARY
:
285 // name = kAnySimpleTypeSchemaType;
286 name
= gSOAPStrings
->kAnyTypeSchemaType
;
288 case nsISchemaBuiltinType::BUILTIN_TYPE_INTEGER
:
289 name
= gSOAPStrings
->kDecimalSchemaType
;
291 case nsISchemaBuiltinType::BUILTIN_TYPE_POSITIVEINTEGER
:
292 name
= gSOAPStrings
->kNonNegativeIntegerSchemaType
;
294 case nsISchemaBuiltinType::BUILTIN_TYPE_NEGATIVEINTEGER
:
295 name
= gSOAPStrings
->kNonPositiveIntegerSchemaType
;
297 case nsISchemaBuiltinType::BUILTIN_TYPE_NONNEGATIVEINTEGER
:
298 name
= gSOAPStrings
->kIntegerSchemaType
;
300 case nsISchemaBuiltinType::BUILTIN_TYPE_NONPOSITIVEINTEGER
:
301 name
= gSOAPStrings
->kIntegerSchemaType
;
303 case nsISchemaBuiltinType::BUILTIN_TYPE_INT
:
304 name
= gSOAPStrings
->kLongSchemaType
;
306 case nsISchemaBuiltinType::BUILTIN_TYPE_UNSIGNEDINT
:
307 name
= gSOAPStrings
->kUnsignedLongSchemaType
;
309 case nsISchemaBuiltinType::BUILTIN_TYPE_LONG
:
310 name
= gSOAPStrings
->kIntegerSchemaType
;
312 case nsISchemaBuiltinType::BUILTIN_TYPE_UNSIGNEDLONG
:
313 name
= gSOAPStrings
->kNonNegativeIntegerSchemaType
;
315 case nsISchemaBuiltinType::BUILTIN_TYPE_SHORT
:
316 name
= gSOAPStrings
->kIntSchemaType
;
318 case nsISchemaBuiltinType::BUILTIN_TYPE_UNSIGNEDSHORT
:
319 name
= gSOAPStrings
->kUnsignedIntSchemaType
;
321 case nsISchemaBuiltinType::BUILTIN_TYPE_DECIMAL
:
322 // name = kAnySimpleTypeSchemaType;
323 name
= gSOAPStrings
->kAnyTypeSchemaType
;
325 case nsISchemaBuiltinType::BUILTIN_TYPE_FLOAT
:
326 // name = kAnySimpleTypeSchemaType;
327 name
= gSOAPStrings
->kAnyTypeSchemaType
;
329 case nsISchemaBuiltinType::BUILTIN_TYPE_DOUBLE
:
330 // name = kAnySimpleTypeSchemaType;
331 name
= gSOAPStrings
->kAnyTypeSchemaType
;
333 case nsISchemaBuiltinType::BUILTIN_TYPE_BOOLEAN
:
334 // name = kAnySimpleTypeSchemaType;
335 name
= gSOAPStrings
->kAnyTypeSchemaType
;
337 case nsISchemaBuiltinType::BUILTIN_TYPE_TIME
:
338 // name = kAnySimpleTypeSchemaType;
339 name
= gSOAPStrings
->kAnyTypeSchemaType
;
341 case nsISchemaBuiltinType::BUILTIN_TYPE_DATETIME
:
342 // name = kAnySimpleTypeSchemaType;
343 name
= gSOAPStrings
->kAnyTypeSchemaType
;
345 case nsISchemaBuiltinType::BUILTIN_TYPE_DURATION
:
346 // name = kAnySimpleTypeSchemaType;
347 name
= gSOAPStrings
->kAnyTypeSchemaType
;
349 case nsISchemaBuiltinType::BUILTIN_TYPE_DATE
:
350 // name = kAnySimpleTypeSchemaType;
351 name
= gSOAPStrings
->kAnyTypeSchemaType
;
353 case nsISchemaBuiltinType::BUILTIN_TYPE_GMONTH
:
354 // name = kAnySimpleTypeSchemaType;
355 name
= gSOAPStrings
->kAnyTypeSchemaType
;
357 case nsISchemaBuiltinType::BUILTIN_TYPE_GYEAR
:
358 // name = kAnySimpleTypeSchemaType;
359 name
= gSOAPStrings
->kAnyTypeSchemaType
;
361 case nsISchemaBuiltinType::BUILTIN_TYPE_GYEARMONTH
:
362 // name = kAnySimpleTypeSchemaType;
363 name
= gSOAPStrings
->kAnyTypeSchemaType
;
365 case nsISchemaBuiltinType::BUILTIN_TYPE_GDAY
:
366 // name = kAnySimpleTypeSchemaType;
367 name
= gSOAPStrings
->kAnyTypeSchemaType
;
369 case nsISchemaBuiltinType::BUILTIN_TYPE_GMONTHDAY
:
370 // name = kAnySimpleTypeSchemaType;
371 name
= gSOAPStrings
->kAnyTypeSchemaType
;
373 case nsISchemaBuiltinType::BUILTIN_TYPE_NAME
:
374 // name = kAnySimpleTypeSchemaType;
375 name
= gSOAPStrings
->kAnyTypeSchemaType
;
377 case nsISchemaBuiltinType::BUILTIN_TYPE_QNAME
:
378 // name = kAnySimpleTypeSchemaType;
379 name
= gSOAPStrings
->kAnyTypeSchemaType
;
381 case nsISchemaBuiltinType::BUILTIN_TYPE_NCNAME
:
382 name
= gSOAPStrings
->kNameSchemaType
;
384 case nsISchemaBuiltinType::BUILTIN_TYPE_ANYURI
:
385 // name = kAnySimpleTypeSchemaType;
386 name
= gSOAPStrings
->kAnyTypeSchemaType
;
388 case nsISchemaBuiltinType::BUILTIN_TYPE_LANGUAGE
:
389 name
= gSOAPStrings
->kTokenSchemaType
;
391 case nsISchemaBuiltinType::BUILTIN_TYPE_ID
:
392 name
= gSOAPStrings
->kNCNameSchemaType
;
394 case nsISchemaBuiltinType::BUILTIN_TYPE_IDREF
:
395 name
= gSOAPStrings
->kNCNameSchemaType
;
397 case nsISchemaBuiltinType::BUILTIN_TYPE_IDREFS
:
398 name
= gSOAPStrings
->kNormalizedStringSchemaType
; // Really a list...
400 case nsISchemaBuiltinType::BUILTIN_TYPE_ENTITY
:
401 name
= gSOAPStrings
->kNCNameSchemaType
;
403 case nsISchemaBuiltinType::BUILTIN_TYPE_ENTITIES
:
404 name
= gSOAPStrings
->kNormalizedStringSchemaType
; // Really a list...
406 case nsISchemaBuiltinType::BUILTIN_TYPE_NOTATION
:
407 // name = kAnySimpleTypeSchemaType;
408 name
= gSOAPStrings
->kAnyTypeSchemaType
;
410 case nsISchemaBuiltinType::BUILTIN_TYPE_NMTOKEN
:
411 name
= gSOAPStrings
->kTokenSchemaType
;
413 case nsISchemaBuiltinType::BUILTIN_TYPE_NMTOKENS
:
414 name
= gSOAPStrings
->kNormalizedStringSchemaType
; // Really a list...
423 if (name
.IsEmpty()) {
425 case nsISchemaType::SCHEMA_TYPE_COMPLEX
:
426 name
= gSOAPStrings
->kAnyTypeSchemaType
;
429 // name = kAnySimpleTypeSchemaType;
430 name
= gSOAPStrings
->kAnyTypeSchemaType
;
433 nsCOMPtr
<nsISchemaCollection
> collection
;
434 rc
= aEncoding
->GetSchemaCollection(getter_AddRefs(collection
));
435 NS_ENSURE_SUCCESS(rc
, rc
);
437 rc
= collection
->GetType(name
,
438 gSOAPStrings
->kXSURI
,
439 getter_AddRefs(base
));
440 // if (NS_FAILED(rc)) return rc;
443 NS_IF_ADDREF(*aResult
= base
);
448 EncodeSimpleValue(nsISOAPEncoding
* aEncoding
,
449 const nsAString
& aValue
,
450 const nsAString
& aNamespaceURI
,
451 const nsAString
& aName
,
452 nsISchemaType
* aSchemaType
,
453 nsIDOMElement
* aDestination
,
454 nsIDOMElement
** aResult
)
457 PRBool needType
= PR_TRUE
;
458 nsAutoString typeName
;
461 rc
= aSchemaType
->GetName(typeName
);
462 NS_ENSURE_SUCCESS(rc
, rc
);
464 rc
= aSchemaType
->GetTargetNamespace(typeNS
);
465 NS_ENSURE_SUCCESS(rc
, rc
);
467 nsAutoString name
; // First choose the appropriate name and namespace for the element.
469 if (aName
.IsEmpty()) { // We automatically choose appropriate element names where none exist.
470 // The idea here seems to be to walk up the schema hierarchy to
471 // find the base type and use the name of that as the element name.
472 ns
= gSOAPStrings
->kSOAPEncURI
;
473 nsAutoString currentURI
= ns
;
474 nsCOMPtr
<nsISchemaType
> currentType
= aSchemaType
;
476 && !(currentURI
.Equals(gSOAPStrings
->kXSURI
) ||
477 currentURI
.Equals(gSOAPStrings
->kSOAPEncURI
))) {
478 nsCOMPtr
<nsISchemaType
> supertype
;
479 rc
= GetSupertype(aEncoding
, currentType
, getter_AddRefs(supertype
));
480 NS_ENSURE_SUCCESS(rc
, rc
);
485 currentType
= supertype
;
486 rc
= currentType
->GetTargetNamespace(currentURI
);
487 NS_ENSURE_SUCCESS(rc
, rc
);
490 rc
= aSchemaType
->GetName(name
);
491 NS_ENSURE_SUCCESS(rc
, rc
);
494 name
= gSOAPStrings
->kAnyTypeSchemaType
;
498 if (!typeNS
.IsEmpty()) {
505 rc
= aEncoding
->GetExternalSchemaURI(gSOAPStrings
->kSOAPEncURI
, ns
);
510 rc
= aEncoding
->GetExternalSchemaURI(aNamespaceURI
, ns
);
512 NS_ENSURE_SUCCESS(rc
, rc
);
514 nsCOMPtr
<nsIDOMDocument
> document
;
515 rc
= aDestination
->GetOwnerDocument(getter_AddRefs(document
));
516 NS_ENSURE_SUCCESS(rc
, rc
);
518 nsCOMPtr
<nsIDOMElement
> element
;
519 rc
= document
->CreateElementNS(ns
, name
, getter_AddRefs(element
));
520 NS_ENSURE_SUCCESS(rc
, rc
);
522 nsCOMPtr
<nsIDOMNode
> ignore
;
523 rc
= aDestination
->AppendChild(element
, getter_AddRefs(ignore
));
524 NS_ENSURE_SUCCESS(rc
, rc
);
527 if (typeNS
.IsEmpty() && typeName
.IsEmpty()) {
528 typeName
= gSOAPStrings
->kAnyTypeSchemaType
;
529 rc
= aEncoding
->GetExternalSchemaURI(gSOAPStrings
->kXSURI
, typeNS
);
530 NS_ENSURE_SUCCESS(rc
, rc
);
534 rc
= nsSOAPUtils::MakeNamespacePrefix(aEncoding
, element
,
536 NS_ENSURE_SUCCESS(rc
, rc
);
538 type
.Append(gSOAPStrings
->kQualifiedSeparator
);
539 type
.Append(typeName
);
540 rc
= aEncoding
->GetExternalSchemaURI(gSOAPStrings
->kXSIURI
, ns
);
541 NS_ENSURE_SUCCESS(rc
, rc
);
544 SetAttributeNS(ns
, gSOAPStrings
->kXSITypeAttribute
, type
);
545 NS_ENSURE_SUCCESS(rc
, rc
);
547 if (!aValue
.IsEmpty()) {
548 nsCOMPtr
<nsIDOMText
> text
;
549 rc
= document
->CreateTextNode(aValue
, getter_AddRefs(text
));
550 NS_ENSURE_SUCCESS(rc
, rc
);
552 rc
= (element
)->AppendChild(text
, getter_AddRefs(ignore
));
553 NS_ENSURE_SUCCESS(rc
, rc
);
556 NS_IF_ADDREF(*aResult
= element
);
560 // Testing for a simple value
561 static nsresult
HasSimpleValue(nsISchemaType
* aSchemaType
, PRBool
* aResult
) {
563 nsresult rc
= aSchemaType
->GetSchemaType(&typevalue
);
564 NS_ENSURE_SUCCESS(rc
, rc
);
566 if (typevalue
== nsISchemaComplexType::SCHEMA_TYPE_COMPLEX
) {
567 nsCOMPtr
<nsISchemaComplexType
> ct
= do_QueryInterface(aSchemaType
);
568 rc
= ct
->GetContentModel(&typevalue
);
569 NS_ENSURE_SUCCESS(rc
, rc
);
571 *aResult
= typevalue
== nsISchemaComplexType::CONTENT_MODEL_SIMPLE
;
581 nsDefaultEncoder::Encode(nsISOAPEncoding
* aEncoding
,
583 const nsAString
& aNamespaceURI
,
584 const nsAString
& aName
,
585 nsISchemaType
* aSchemaType
,
586 nsISOAPAttachments
* aAttachments
,
587 nsIDOMElement
* aDestination
,
588 nsIDOMElement
** aReturnValue
)
590 NS_ENSURE_ARG_POINTER(aEncoding
);
591 NS_ENSURE_ARG_POINTER(aDestination
);
592 NS_ENSURE_ARG_POINTER(aReturnValue
);
593 *aReturnValue
= nsnull
;
594 if (aSource
== nsnull
) {
596 nsresult rc
= aEncoding
->GetExternalSchemaURI(gSOAPStrings
->kXSIURI
, ns
);
597 NS_ENSURE_SUCCESS(rc
, rc
);
600 if (!aName
.IsEmpty())
601 name
.Assign(gSOAPStrings
->kNull
);
602 rc
= EncodeSimpleValue(aEncoding
, gSOAPStrings
->kEmpty
, gSOAPStrings
->kEmpty
,
603 name
, nsnull
, aDestination
, aReturnValue
);
604 NS_ENSURE_SUCCESS(rc
, rc
);
606 rc
= (*aReturnValue
)->SetAttributeNS(ns
, gSOAPStrings
->kNull
, gSOAPStrings
->kTrueA
);
607 NS_ENSURE_SUCCESS(rc
, rc
);
609 nsCOMPtr
<nsISOAPEncoder
> encoder
;
611 nsCOMPtr
<nsISchemaType
> lookupType
= aSchemaType
;
613 nsAutoString schemaType
;
614 nsAutoString schemaURI
;
615 nsAutoString encodingKey
;
616 nsresult rc
= lookupType
->GetName(schemaType
);
617 NS_ENSURE_SUCCESS(rc
, rc
);
619 rc
= lookupType
->GetTargetNamespace(schemaURI
);
620 NS_ENSURE_SUCCESS(rc
, rc
);
622 SOAPEncodingKey(schemaURI
, schemaType
, encodingKey
);
623 rc
= aEncoding
->GetEncoder(encodingKey
, getter_AddRefs(encoder
));
624 NS_ENSURE_SUCCESS(rc
, rc
);
628 nsCOMPtr
<nsISchemaType
> supertype
;
629 rc
= GetSupertype(aEncoding
, lookupType
, getter_AddRefs(supertype
));
630 NS_ENSURE_SUCCESS(rc
, rc
);
632 lookupType
= supertype
;
637 nsAutoString encodingKey
;
638 SOAPEncodingKey(gSOAPStrings
->kXSURI
,
639 gSOAPStrings
->kAnyTypeSchemaType
, encodingKey
);
641 aEncoding
->GetEncoder(encodingKey
, getter_AddRefs(encoder
));
642 NS_ENSURE_SUCCESS(rc
, rc
);
645 return encoder
->Encode(aEncoding
, aSource
, aNamespaceURI
, aName
,
646 aSchemaType
, aAttachments
, aDestination
,
649 return SOAP_EXCEPTION(NS_ERROR_NOT_IMPLEMENTED
,
650 "SOAP_NO_ENCODER_FOR_TYPE",
651 "The default encoder finds no encoder for specific type");
655 GetNativeType(PRUint16 aType
, nsAString
& aSchemaNamespaceURI
, nsAString
& aSchemaType
)
657 aSchemaNamespaceURI
.Assign(gSOAPStrings
->kXSURI
);
659 case nsIDataType::VTYPE_CHAR_STR
:
660 case nsIDataType::VTYPE_WCHAR_STR
:
661 case nsIDataType::VTYPE_CHAR
:
662 case nsIDataType::VTYPE_WCHAR
:
663 case nsIDataType::VTYPE_STRING_SIZE_IS
:
664 case nsIDataType::VTYPE_WSTRING_SIZE_IS
:
665 case nsIDataType::VTYPE_ASTRING
:
666 case nsIDataType::VTYPE_DOMSTRING
:
667 case nsIDataType::VTYPE_CSTRING
:
668 case nsIDataType::VTYPE_UTF8STRING
:
669 aSchemaType
.Assign(gSOAPStrings
->kStringSchemaType
);
671 case nsIDataType::VTYPE_INT8
:
672 aSchemaType
.Assign(gSOAPStrings
->kByteSchemaType
);
674 case nsIDataType::VTYPE_INT16
:
675 aSchemaType
.Assign(gSOAPStrings
->kShortSchemaType
);
677 case nsIDataType::VTYPE_INT32
:
678 aSchemaType
.Assign(gSOAPStrings
->kIntSchemaType
);
680 case nsIDataType::VTYPE_INT64
:
681 aSchemaType
.Assign(gSOAPStrings
->kLongSchemaType
);
683 case nsIDataType::VTYPE_UINT8
:
684 aSchemaType
.Assign(gSOAPStrings
->kUnsignedByteSchemaType
);
686 case nsIDataType::VTYPE_UINT16
:
687 aSchemaType
.Assign(gSOAPStrings
->kUnsignedShortSchemaType
);
689 case nsIDataType::VTYPE_UINT32
:
690 aSchemaType
.Assign(gSOAPStrings
->kUnsignedIntSchemaType
);
692 case nsIDataType::VTYPE_UINT64
:
693 aSchemaType
.Assign(gSOAPStrings
->kUnsignedLongSchemaType
);
695 case nsIDataType::VTYPE_FLOAT
:
696 aSchemaType
.Assign(gSOAPStrings
->kFloatSchemaType
);
698 case nsIDataType::VTYPE_DOUBLE
:
699 aSchemaType
.Assign(gSOAPStrings
->kDoubleSchemaType
);
701 case nsIDataType::VTYPE_BOOL
:
702 aSchemaType
.Assign(gSOAPStrings
->kBooleanSchemaType
);
704 case nsIDataType::VTYPE_ARRAY
:
705 case nsIDataType::VTYPE_EMPTY_ARRAY
:
706 aSchemaType
.Assign(gSOAPStrings
->kArraySOAPType
);
707 aSchemaNamespaceURI
.Assign(gSOAPStrings
->kSOAPEncURI
);
709 // case nsIDataType::VTYPE_VOID:
710 // case nsIDataType::VTYPE_EMPTY:
711 // Empty may be either simple or complex.
713 case nsIDataType::VTYPE_INTERFACE_IS
:
714 case nsIDataType::VTYPE_INTERFACE
:
715 aSchemaType
.Assign(gSOAPStrings
->kStructSOAPType
);
716 aSchemaNamespaceURI
.Assign(gSOAPStrings
->kSOAPEncURI
);
719 aSchemaType
.Assign(gSOAPStrings
->kAnySimpleTypeSchemaType
);
724 nsAnyTypeEncoder::Encode(nsISOAPEncoding
* aEncoding
,
726 const nsAString
& aNamespaceURI
,
727 const nsAString
& aName
,
728 nsISchemaType
* aSchemaType
,
729 nsISOAPAttachments
* aAttachments
,
730 nsIDOMElement
* aDestination
,
731 nsIDOMElement
** aReturnValue
)
733 NS_ENSURE_ARG_POINTER(aEncoding
);
734 NS_ENSURE_ARG_POINTER(aDestination
);
735 NS_ENSURE_ARG_POINTER(aReturnValue
);
736 *aReturnValue
= nsnull
;
737 nsAutoString nativeSchemaType
;
738 nsAutoString nativeSchemaURI
;
740 nsresult rc
= aSource
->GetDataType(&typevalue
);
741 NS_ENSURE_SUCCESS(rc
, rc
);
743 // If there is a schema type then regular native types will not avail us anything.
745 PRBool simple
= PR_FALSE
;
746 rc
= HasSimpleValue(aSchemaType
, &simple
);
747 NS_ENSURE_SUCCESS(rc
, rc
);
751 case nsIDataType::VTYPE_ARRAY
:
752 case nsIDataType::VTYPE_EMPTY_ARRAY
:
753 case nsIDataType::VTYPE_INTERFACE_IS
:
754 case nsIDataType::VTYPE_INTERFACE
:
760 nativeSchemaType
.Assign(gSOAPStrings
->kAnySimpleTypeSchemaType
);
761 nativeSchemaURI
.Assign(gSOAPStrings
->kXSURI
);
764 nativeSchemaType
.Assign(gSOAPStrings
->kStructSOAPType
);
765 nativeSchemaURI
.Assign(gSOAPStrings
->kSOAPEncURI
);
769 GetNativeType(typevalue
, nativeSchemaURI
, nativeSchemaType
);
772 nsCOMPtr
<nsISOAPEncoder
> encoder
;
773 nsAutoString encodingKey
;
774 SOAPEncodingKey(nativeSchemaURI
, nativeSchemaType
, encodingKey
);
775 rc
= aEncoding
->GetEncoder(encodingKey
, getter_AddRefs(encoder
));
776 NS_ENSURE_SUCCESS(rc
, rc
);
779 nsCOMPtr
<nsISchemaType
> type
;
784 nsCOMPtr
<nsISchemaCollection
> collection
;
786 aEncoding
->GetSchemaCollection(getter_AddRefs(collection
));
787 NS_ENSURE_SUCCESS(rc
, rc
);
789 rc
= collection
->GetType(nativeSchemaType
,
791 getter_AddRefs(type
));
792 // if (NS_FAILED(rc)) return rc;
795 return encoder
->Encode(aEncoding
, aSource
, aNamespaceURI
, aName
,
796 type
, aAttachments
, aDestination
,
799 return SOAP_EXCEPTION(NS_ERROR_NOT_IMPLEMENTED
,
800 "SOAP_NO_ENCODER_FOR_TYPE",
801 "The any type encoder finds no encoder for specific data");
804 static nsresult
EncodeStructParticle(nsISOAPEncoding
* aEncoding
, nsIPropertyBag
* aPropertyBag
,
805 nsISchemaParticle
* aParticle
,
806 nsISOAPAttachments
* aAttachments
, nsIDOMElement
* aDestination
)
811 rc
= aParticle
->GetMinOccurs(&minOccurs
);
812 NS_ENSURE_SUCCESS(rc
, rc
);
815 rc
= aParticle
->GetMaxOccurs(&maxOccurs
);
816 NS_ENSURE_SUCCESS(rc
, rc
);
818 PRUint16 particleType
;
819 rc
= aParticle
->GetParticleType(&particleType
);
820 NS_ENSURE_SUCCESS(rc
, rc
);
822 switch(particleType
) {
823 case nsISchemaParticle::PARTICLE_TYPE_ELEMENT
: {
824 if (maxOccurs
> 1) { // Todo: Try to make this thing work as an array?
825 return NS_ERROR_NOT_AVAILABLE
; // For now, we just try something else if we can (recoverable)
827 nsCOMPtr
<nsISchemaElement
> element
= do_QueryInterface(aParticle
);
829 rc
= element
->GetTargetNamespace(name
);
830 NS_ENSURE_SUCCESS(rc
, rc
);
832 if (!name
.IsEmpty()) {
833 rc
= NS_ERROR_NOT_AVAILABLE
; // No known way to use namespace qualification in struct
836 rc
= element
->GetName(name
);
837 NS_ENSURE_SUCCESS(rc
, rc
);
839 rc
= element
->GetName(name
);
840 NS_ENSURE_SUCCESS(rc
, rc
);
842 nsCOMPtr
<nsISchemaType
> type
;
843 rc
= element
->GetType(getter_AddRefs(type
));
844 NS_ENSURE_SUCCESS(rc
, rc
);
846 nsCOMPtr
<nsIVariant
> value
;
847 rc
= aPropertyBag
->GetProperty(name
, getter_AddRefs(value
));
848 if (NS_SUCCEEDED(rc
)) {
849 nsCOMPtr
<nsIDOMElement
> dummy
;
850 rc
= aEncoding
->Encode(value
, gSOAPStrings
->kEmpty
, name
, type
, aAttachments
, aDestination
, getter_AddRefs(dummy
));
851 NS_ENSURE_SUCCESS(rc
, rc
);
854 if (minOccurs
== 0 && rc
== NS_ERROR_NOT_AVAILABLE
) {
855 // If we succeeded or failed recoverably, but we were permitted to,
856 // then return success
861 case nsISchemaParticle::PARTICLE_TYPE_MODEL_GROUP
:
863 if (maxOccurs
> 1) { // Todo: Try to make this thing work as an array?
864 return NS_ERROR_NOT_AVAILABLE
; // For now, we just try something else if we can (recoverable)
866 nsCOMPtr
<nsISchemaModelGroup
> modelGroup
= do_QueryInterface(aParticle
);
868 rc
= modelGroup
->GetCompositor(&compositor
);
869 NS_ENSURE_SUCCESS(rc
, rc
);
871 PRUint32 particleCount
;
872 rc
= modelGroup
->GetParticleCount(&particleCount
);
873 NS_ENSURE_SUCCESS(rc
, rc
);
876 for (i
= 0; i
< particleCount
; i
++) {
877 nsCOMPtr
<nsISchemaParticle
> child
;
878 rc
= modelGroup
->GetParticle(i
, getter_AddRefs(child
));
879 NS_ENSURE_SUCCESS(rc
, rc
);
881 rc
= EncodeStructParticle(aEncoding
, aPropertyBag
, child
, aAttachments
, aDestination
);
882 if (compositor
== nsISchemaModelGroup::COMPOSITOR_CHOICE
) {
883 if (NS_SUCCEEDED(rc
)) {
886 if (rc
== NS_ERROR_NOT_AVAILABLE
) { // In a choice, recoverable model failures are OK.
890 else if (i
> 0 && rc
== NS_ERROR_NOT_AVAILABLE
) { // This detects ambiguous model (non-deterministic choice which fails after succeeding on first)
891 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
892 "SOAP_AMBIGUOUS_ENCODING",
893 "Cannot proceed due to ambiguity or error in content model");
898 if (compositor
== nsISchemaModelGroup::COMPOSITOR_CHOICE
) // If choice selected nothing, this is recoverable failure
899 rc
= NS_ERROR_NOT_AVAILABLE
;
900 if (minOccurs
== 0 && rc
== NS_ERROR_NOT_AVAILABLE
) // If we succeeded or failed recoverably, but we were permitted to, then return success
902 return rc
; // Return status
904 case nsISchemaParticle::PARTICLE_TYPE_ANY
:
905 // No model available here (we may wish to handle strict versus lazy, but what does that mean with only local accessor names)
911 nsCOMPtr
<nsISimpleEnumerator
> e
;
912 rc
= aPropertyBag
->GetEnumerator(getter_AddRefs(e
));
913 NS_ENSURE_SUCCESS(rc
, rc
);
916 rc
= e
->HasMoreElements(&more
);
917 NS_ENSURE_SUCCESS(rc
, rc
);
920 nsCOMPtr
<nsIProperty
> p
;
921 rc
= e
->GetNext(getter_AddRefs(p
));
922 NS_ENSURE_SUCCESS(rc
, rc
);
925 rc
= p
->GetName(name
);
926 NS_ENSURE_SUCCESS(rc
, rc
);
928 nsCOMPtr
<nsIVariant
>value
;
929 rc
= p
->GetValue(getter_AddRefs(value
));
930 NS_ENSURE_SUCCESS(rc
, rc
);
932 nsCOMPtr
<nsIDOMElement
>result
;
933 rc
= aEncoding
->Encode(value
,gSOAPStrings
->kEmpty
,name
,nsnull
,aAttachments
,aDestination
,getter_AddRefs(result
));
934 NS_ENSURE_SUCCESS(rc
, rc
);
936 rc
= e
->HasMoreElements(&more
);
937 NS_ENSURE_SUCCESS(rc
, rc
);
943 nsStructEncoder::Encode(nsISOAPEncoding
* aEncoding
,
944 nsIVariant
* aSource
,
945 const nsAString
& aNamespaceURI
,
946 const nsAString
& aName
,
947 nsISchemaType
* aSchemaType
,
948 nsISOAPAttachments
* aAttachments
,
949 nsIDOMElement
* aDestination
,
950 nsIDOMElement
* *aReturnValue
)
952 NS_ENSURE_ARG_POINTER(aEncoding
);
953 NS_ENSURE_ARG_POINTER(aDestination
);
954 NS_ENSURE_ARG_POINTER(aReturnValue
);
955 *aReturnValue
= nsnull
;
957 nsCOMPtr
<nsISupports
> ptr
;
958 nsresult rc
= aSource
->GetAsInterface(&iid
, getter_AddRefs(ptr
));
959 NS_ENSURE_SUCCESS(rc
, rc
);
961 nsCOMPtr
<nsIPropertyBag
>pbptr
= do_QueryInterface(ptr
);
962 if (pbptr
) { // Do any object that can QI to a property bag.
963 nsCOMPtr
<nsISchemaModelGroup
>modelGroup
;
965 nsCOMPtr
<nsISchemaComplexType
>ctype
= do_QueryInterface(aSchemaType
);
967 rc
= ctype
->GetModelGroup(getter_AddRefs(modelGroup
));
968 NS_ENSURE_SUCCESS(rc
, rc
);
971 // We still have to fake this one, because there is no struct type in schema.
972 if (aName
.IsEmpty() && !aSchemaType
) {
973 rc
= EncodeSimpleValue(aEncoding
, gSOAPStrings
->kEmpty
,
974 gSOAPStrings
->kSOAPEncURI
,
975 gSOAPStrings
->kStructSOAPType
,
976 aSchemaType
, aDestination
,
980 rc
= EncodeSimpleValue(aEncoding
, gSOAPStrings
->kEmpty
,
981 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
984 NS_ENSURE_SUCCESS(rc
, rc
);
986 return EncodeStructParticle(aEncoding
, pbptr
, modelGroup
, aAttachments
, *aReturnValue
);
988 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
989 "SOAP_PROPERTYBAG_REQUIRED",
990 "When encoding as a struct, an object with properties is required");
996 nsAnySimpleTypeEncoder::Encode(nsISOAPEncoding
* aEncoding
,
997 nsIVariant
* aSource
,
998 const nsAString
& aNamespaceURI
,
999 const nsAString
& aName
,
1000 nsISchemaType
* aSchemaType
,
1001 nsISOAPAttachments
* aAttachments
,
1002 nsIDOMElement
* aDestination
,
1003 nsIDOMElement
* *aReturnValue
)
1005 NS_ENSURE_ARG_POINTER(aEncoding
);
1006 NS_ENSURE_ARG_POINTER(aDestination
);
1007 NS_ENSURE_ARG_POINTER(aReturnValue
);
1008 *aReturnValue
= nsnull
;
1011 rc
= aSource
->GetAsAString(value
);
1012 NS_ENSURE_SUCCESS(rc
, rc
);
1014 // We still have to fake this one, because there is no any simple type in schema.
1015 if (aName
.IsEmpty() && !aSchemaType
) {
1016 return EncodeSimpleValue(aEncoding
,
1018 gSOAPStrings
->kSOAPEncURI
,
1019 gSOAPStrings
->kAnySimpleTypeSchemaType
,
1024 return EncodeSimpleValue(aEncoding
,
1034 * Handle SOAP element mark as null with xsi:null or xsi:nil.
1036 * @param aEncoding SOAP encoding (in).
1037 * @param aSource SOAP DOM element (in).
1038 * @param aSchemaType Type of the SOAP element (in).
1039 * @param aAttachments (in).
1040 * @param aNullAttr Value for a xsi:null of xsi:nil attribute,
1041 * could be either true or 1 (in).
1042 * @param aResult Value for this element (out).
1044 static nsresult
HandleNull(nsISOAPEncoding
* aEncoding
,
1045 nsIDOMElement
* aSource
,
1046 nsISchemaType
* aSchemaType
,
1047 nsISOAPAttachments
* aAttachments
,
1048 nsAutoString aNullAttr
,
1049 nsIVariant
** aResult
)
1051 NS_ENSURE_ARG_POINTER(aEncoding
);
1052 NS_ENSURE_ARG_POINTER(aSource
);
1053 NS_ENSURE_ARG_POINTER(aResult
);
1055 if (aNullAttr
.Equals(gSOAPStrings
->kTrue
) ||
1056 aNullAttr
.Equals(gSOAPStrings
->kTrueA
)) {
1058 PRUint16 schemaType
;
1059 nsAutoString typeName
;
1062 aSchemaType
->GetSchemaType(&schemaType
);
1063 aSchemaType
->GetName(typeName
);
1066 nsCOMPtr
<nsIWritableVariant
> nullVariant(do_CreateInstance("@mozilla.org/variant;1"));
1068 return NS_ERROR_OUT_OF_MEMORY
;
1072 (typeName
.Equals(NS_LITERAL_STRING("string")) ||
1073 typeName
.Equals(NS_LITERAL_STRING("normalizedString")))) {
1075 nsAutoString strVal
;
1076 strVal
.SetIsVoid(true);
1078 nullVariant
->SetAsAString(strVal
);
1080 nullVariant
->SetAsISupports(nsnull
);
1083 NS_ADDREF(*aResult
= nullVariant
);
1085 } else if (!(aNullAttr
.Equals(gSOAPStrings
->kFalse
) ||
1086 aNullAttr
.Equals(gSOAPStrings
->kFalseA
))) {
1088 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
1090 "The value of the nill attribute must be true or false.");
1093 NS_ERROR("How have you get here ?");
1096 return NS_ERROR_UNEXPECTED
;
1100 * SOAP code should be given the explit type not to have to look for it.
1101 * Get explicit schema type from SOAP DOM element.
1103 * @param aEncoding SOAP encoding (in).
1104 * @param aElement DOM element from SOAP response (in).
1105 * @param aResult Explicit schema type [xsi:type] (out).
1107 static nsresult
GetExplicitType(nsISOAPEncoding
* aEncoding
,
1108 nsIDOMElement
* aElement
,
1109 nsISchemaType
** aResult
)
1111 NS_ENSURE_ARG_POINTER(aEncoding
);
1112 NS_ENSURE_ARG_POINTER(aElement
);
1114 nsresult rc
= NS_OK
;
1115 nsCOMPtr
<nsISchemaLoader
> schemaLoader
=
1116 do_GetService(NS_SCHEMALOADER_CONTRACTID
, &rc
);
1117 NS_ENSURE_SUCCESS(rc
, rc
);
1118 nsAutoString explicitType
;
1120 if (nsSOAPUtils::GetAttribute(aEncoding
, aElement
, gSOAPStrings
->kXSIURI
,
1121 gSOAPStrings
->kXSITypeAttribute
,
1125 nsCOMPtr
<nsISchemaType
> type
;
1127 rc
= nsSOAPUtils::GetNamespaceURI(aEncoding
, aElement
, explicitType
, ns
);
1128 NS_ENSURE_SUCCESS(rc
, rc
);
1129 rc
= nsSOAPUtils::GetLocalName(explicitType
, name
);
1130 NS_ENSURE_SUCCESS(rc
, rc
);
1132 nsCOMPtr
<nsISchemaCollection
> col
= do_QueryInterface(schemaLoader
);
1133 rc
= col
->GetType(name
, ns
, getter_AddRefs(type
));
1135 NS_IF_ADDREF(*aResult
= type
);
1139 NS_ERROR("::GetExplicitType: Wow how do you get here");
1142 return NS_ERROR_UNEXPECTED
;
1146 * Recursive method used by array encoding which counts the sizes of
1147 * the specified dimensions and does a very primitive determination whether
1148 * all the members of the array are of a single homogenious type.
1149 * This intelligently skips nulls wherever they occur.
1151 static nsresult
GetArrayType(nsIVariant
* aSource
,
1152 PRUint32 aDimensionCount
,
1153 PRUint32
* aDimensionSizes
,
1157 *aType
= nsIDataType::VTYPE_EMPTY
;
1166 rc
= aSource
->GetDataType(&type
);
1167 NS_ENSURE_SUCCESS(rc
, rc
);
1169 if (type
== nsIDataType::VTYPE_EMPTY
||
1170 type
== nsIDataType::VTYPE_VOID
||
1171 type
== nsIDataType::VTYPE_EMPTY_ARRAY
) {
1174 type
= nsIDataType::VTYPE_EMPTY
;
1178 rc
= aSource
->GetAsArray(&type
, &iid
, &count
, &array
); // First, get the array, if any.
1179 NS_ENSURE_SUCCESS(rc
, rc
);
1181 if (count
> aDimensionSizes
[0]) {
1182 aDimensionSizes
[0] = count
;
1184 if (aDimensionCount
> 1) {
1185 if (type
!= nsIDataType::VTYPE_INTERFACE_IS
||
1186 !iid
.Equals(NS_GET_IID(nsIVariant
))) {
1187 rc
= SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,"SOAP_ARRAY_OBJECTS","When encoding as an array, an array of array objects is required");
1188 // All nested arrays (which is what multi-dimensional arrays are) are variants.
1191 nsIVariant
** a
= static_cast<nsIVariant
**>(array
);
1192 PRUint16 rtype
= nsIDataType::VTYPE_EMPTY
;
1193 for (i
= 0; i
< count
; i
++) {
1195 rc
= GetArrayType(a
[i
], aDimensionCount
- 1, aDimensionSizes
+ 1, &nexttype
);
1198 if (rtype
== nsIDataType::VTYPE_EMPTY
)
1200 else if (nexttype
!= nsIDataType::VTYPE_EMPTY
1201 && nexttype
!= rtype
)
1202 rtype
= nsIDataType::VTYPE_INTERFACE_IS
;
1210 // The memory model for variant arrays' GetAsArray is difficult to manage
1212 case nsIDataType::VTYPE_INTERFACE_IS
:
1214 nsISupports
** values
= static_cast<nsISupports
**>(array
);
1215 for (i
= 0; i
< count
; i
++)
1216 NS_RELEASE(values
[i
]);
1219 case nsIDataType::VTYPE_WCHAR_STR
:
1220 case nsIDataType::VTYPE_CHAR_STR
:
1222 void** ptrs
= static_cast<void**>(array
);
1223 for (i
= 0; i
< count
; i
++) {
1224 nsMemory::Free(ptrs
[i
]);
1229 nsMemory::Free(array
);
1230 { // Individual lengths guaranteed to fit because variant array length is 32-bit.
1231 PRUint64 tot
= 1; // Collect in 64 bits, just to make sure combo fits
1232 for (i
= 0; i
< aDimensionCount
; i
++) {
1233 tot
= tot
* aDimensionSizes
[i
];
1234 if (tot
> 0xffffffffU
) {
1235 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
1236 "SOAP_ARRAY_TOO_BIG",
1237 "When encoding an object as an array, the total count of items exceeded maximum.");
1244 * Recursive method used by array encoding to encode the next level of the array into the
1245 * established array element. If dimension count is > 1, then it recursively doles out
1246 * the work. This intelligently skips nulls wherever they occur.
1248 static nsresult
EncodeArray(nsISOAPEncoding
* aEncoding
, nsIVariant
* aSource
, nsISchemaType
* aSchemaType
,
1249 nsISOAPAttachments
* aAttachments
, nsIDOMElement
* aArray
, PRUint32 aDimensionCount
, PRUint32
* aDimensionSizes
)
1256 if (aSource
!= nsnull
) {
1257 rc
= aSource
->GetDataType(&type
);
1258 NS_ENSURE_SUCCESS(rc
, rc
);
1260 if (type
== nsIDataType::VTYPE_EMPTY
||
1261 type
== nsIDataType::VTYPE_VOID
||
1262 type
== nsIDataType::VTYPE_EMPTY_ARRAY
) {
1265 type
= nsIDataType::VTYPE_EMPTY
;
1269 rc
= aSource
->GetAsArray(&type
, &iid
, &count
, &array
); // First, get the array, if any.
1270 NS_ENSURE_SUCCESS(rc
, rc
);
1273 else { // If the source is null, then just add a bunch of nulls to the array.
1274 count
= (PRUint32
)aDimensionSizes
[--aDimensionCount
];
1275 while (aDimensionCount
)
1276 count
*= (PRUint32
)aDimensionSizes
[--aDimensionCount
];
1279 nsCOMPtr
<nsIDOMElement
> cloneable
;
1280 rc
= aEncoding
->GetExternalSchemaURI(gSOAPStrings
->kXSIURI
, ns
);
1281 NS_ENSURE_SUCCESS(rc
, rc
);
1283 rc
= EncodeSimpleValue(aEncoding
, gSOAPStrings
->kEmpty
, gSOAPStrings
->kEmpty
,
1284 gSOAPStrings
->kNull
, nsnull
, aArray
, getter_AddRefs(cloneable
));
1285 NS_ENSURE_SUCCESS(rc
, rc
);
1287 rc
= cloneable
->SetAttributeNS(ns
, gSOAPStrings
->kNull
, gSOAPStrings
->kTrueA
);
1288 NS_ENSURE_SUCCESS(rc
, rc
);
1290 nsCOMPtr
<nsIDOMNode
> clone
;
1291 nsCOMPtr
<nsIDOMNode
> dummy
;
1293 rc
= cloneable
->CloneNode(PR_TRUE
, getter_AddRefs(clone
));// No children so deep == shallow
1294 NS_ENSURE_SUCCESS(rc
, rc
);
1296 rc
= aArray
->AppendChild(clone
, getter_AddRefs(dummy
));
1297 NS_ENSURE_SUCCESS(rc
, rc
);
1301 nsCOMPtr
<nsIDOMElement
> dummy
;
1302 PRBool freeptrs
= PR_FALSE
;
1305 // The more-robust way of encoding is to construct variants and call the encoder directly,
1306 // but for now, we short-circuit it for simple types.
1308 #define ENCODE_SIMPLE_ARRAY(XPType, VType, Source) \
1310 XPType* values = static_cast<XPType*>(array); \
1311 nsCOMPtr<nsIWritableVariant> p = \
1312 do_CreateInstance(NS_VARIANT_CONTRACTID, &rc); \
1313 if (NS_FAILED(rc)) break; \
1314 for (i = 0; i < count; i++) { \
1315 if (NS_FAILED(rc)) \
1317 rc = p->SetAs##VType(Source); \
1318 if (NS_FAILED(rc)) \
1320 rc = aEncoding->Encode(p, \
1321 gSOAPStrings->kEmpty, \
1322 gSOAPStrings->kEmpty, \
1326 getter_AddRefs(dummy)); \
1327 if (NS_FAILED(rc)) break; \
1332 if (aDimensionCount
> 1) {
1334 case nsIDataType::VTYPE_INTERFACE_IS
:
1336 nsIVariant
** values
= static_cast<nsIVariant
**>(array
);// If not truly a variant, we only release.
1337 if (iid
.Equals(NS_GET_IID(nsIVariant
))) { // Only do variants for now.
1338 for (i
= 0; i
< count
; i
++) {
1339 rc
= EncodeArray(aEncoding
, values
[i
],
1343 aDimensionCount
- 1,
1344 aDimensionSizes
+ 1);
1345 if (NS_FAILED(rc
)) break;
1348 for (i
= 0; i
< count
; i
++)
1349 NS_RELEASE(values
[i
]);
1352 case nsIDataType::VTYPE_WCHAR_STR
:
1353 case nsIDataType::VTYPE_CHAR_STR
:
1356 rc
= SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,"SOAP_ARRAY_OBJECTS","When encoding as an array, an array of array objects is required");
1358 } else switch (type
) {
1359 case nsIDataType::VTYPE_INT8
:
1360 ENCODE_SIMPLE_ARRAY(PRUint8
, Int8
,
1361 (signed char) values
[i
]);
1362 case nsIDataType::VTYPE_INT16
:
1363 ENCODE_SIMPLE_ARRAY(PRInt16
, Int16
, values
[i
]);
1364 case nsIDataType::VTYPE_INT32
:
1365 ENCODE_SIMPLE_ARRAY(PRInt32
, Int32
, values
[i
]);
1366 case nsIDataType::VTYPE_INT64
:
1367 ENCODE_SIMPLE_ARRAY(PRInt64
, Int64
, values
[i
]);
1368 case nsIDataType::VTYPE_UINT8
:
1369 ENCODE_SIMPLE_ARRAY(PRUint8
, Uint8
, values
[i
]);
1370 case nsIDataType::VTYPE_UINT16
:
1371 ENCODE_SIMPLE_ARRAY(PRUint16
, Uint16
, values
[i
]);
1372 case nsIDataType::VTYPE_UINT32
:
1373 ENCODE_SIMPLE_ARRAY(PRUint32
, Uint32
, values
[i
]);
1374 case nsIDataType::VTYPE_UINT64
:
1375 ENCODE_SIMPLE_ARRAY(PRUint64
, Uint64
, values
[i
]);
1376 case nsIDataType::VTYPE_FLOAT
:
1377 ENCODE_SIMPLE_ARRAY(float, Float
, values
[i
]);
1378 case nsIDataType::VTYPE_DOUBLE
:
1379 ENCODE_SIMPLE_ARRAY(double, Double
, values
[i
]);
1380 case nsIDataType::VTYPE_BOOL
:
1381 ENCODE_SIMPLE_ARRAY(PRBool
, Bool
, (PRUint16
) values
[i
]);
1382 case nsIDataType::VTYPE_ID
:
1383 case nsIDataType::VTYPE_CHAR_STR
:
1385 ENCODE_SIMPLE_ARRAY(char *, String
, values
[i
]);
1386 case nsIDataType::VTYPE_WCHAR_STR
:
1388 ENCODE_SIMPLE_ARRAY(PRUnichar
*, WString
, values
[i
]);
1389 case nsIDataType::VTYPE_CHAR
:
1390 ENCODE_SIMPLE_ARRAY(char, Char
, values
[i
]);
1391 case nsIDataType::VTYPE_WCHAR
:
1392 ENCODE_SIMPLE_ARRAY(PRUnichar
, WChar
, values
[i
]);
1393 case nsIDataType::VTYPE_INTERFACE_IS
:
1395 nsIVariant
** values
= static_cast<nsIVariant
**>(array
);// If not truly a variant, we only use as nsISupports
1396 if (iid
.Equals(NS_GET_IID(nsIVariant
))) { // Only do variants for now.
1397 for (i
= 0; i
< count
; i
++) {
1398 rc
= aEncoding
->Encode(values
[i
],
1399 gSOAPStrings
->kEmpty
,
1400 gSOAPStrings
->kEmpty
,
1404 getter_AddRefs(dummy
));
1405 if (NS_FAILED(rc
)) break;
1409 nsCOMPtr
<nsIWritableVariant
> p
=
1410 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
1411 if (NS_FAILED(rc
)) break;
1412 for (i
= 0; i
< count
; i
++) {
1415 rc
= p
->SetAsInterface(iid
, values
[i
]);
1418 rc
= aEncoding
->Encode(p
,
1419 gSOAPStrings
->kEmpty
,
1420 gSOAPStrings
->kEmpty
,
1424 getter_AddRefs(dummy
));
1425 if (NS_FAILED(rc
)) break;
1428 for (i
= 0; i
< count
; i
++)
1429 NS_RELEASE(values
[i
]);
1433 case nsIDataType::VTYPE_EMPTY_ARRAY
:
1434 case nsIDataType::VTYPE_EMPTY
:
1435 break; // I think an empty array needs no elements?
1436 // Don't support these array types, as they seem meaningless.
1437 case nsIDataType::VTYPE_ASTRING
:
1438 case nsIDataType::VTYPE_VOID
:
1439 case nsIDataType::VTYPE_INTERFACE
:
1440 case nsIDataType::VTYPE_ARRAY
:
1441 rc
= SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,"SOAP_ARRAY_TYPES","When encoding an array, unable to handle array elements");
1444 void** ptrs
= static_cast<void**>(array
);
1445 for (i
= 0; i
< count
; i
++) {
1446 nsMemory::Free(ptrs
[i
]);
1448 nsMemory::Free(array
);
1450 // We know that count does not exceed size of dimension, but it may be less
1455 nsArrayEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1456 nsIVariant
* aSource
,
1457 const nsAString
& aNamespaceURI
,
1458 const nsAString
& aName
,
1459 nsISchemaType
* aSchemaType
,
1460 nsISOAPAttachments
* aAttachments
,
1461 nsIDOMElement
* aDestination
,
1462 nsIDOMElement
* *aReturnValue
)
1464 NS_ENSURE_ARG_POINTER(aEncoding
);
1465 NS_ENSURE_ARG_POINTER(aDestination
);
1466 NS_ENSURE_ARG_POINTER(aReturnValue
);
1467 *aReturnValue
= nsnull
;
1468 PRUint16 arrayNativeType
;
1469 PRUint32 dimensionSizes
[MAX_ARRAY_DIMENSIONS
];
1471 PRUint32 dimensionCount
= 1;
1472 nsCOMPtr
<nsISchemaType
> schemaArrayType
;
1475 nsresult rc
= aSchemaType
->GetSchemaType(&type
);
1476 NS_ENSURE_SUCCESS(rc
, rc
);
1478 if (type
== nsISchemaType::SCHEMA_TYPE_COMPLEX
) {
1479 nsCOMPtr
<nsISchemaComplexType
> ct
= do_QueryInterface(aSchemaType
);
1480 nsresult rc
= ct
->GetArrayDimension(&dimensionCount
);
1481 NS_ENSURE_SUCCESS(rc
, rc
);
1483 if (dimensionCount
== 0) {
1487 // Arrays with no defaults are supposed to return 0, but apparently do not
1488 rc
= ct
->GetArrayType(getter_AddRefs(schemaArrayType
));
1489 NS_ENSURE_SUCCESS(rc
, rc
);
1493 for (i
= 0; i
< dimensionCount
; i
++)
1494 dimensionSizes
[i
] = 0;
1495 // Look over the array and find its dimensions and common type.
1496 nsresult rc
= GetArrayType(aSource
, dimensionCount
, dimensionSizes
, &arrayNativeType
);
1497 NS_ENSURE_SUCCESS(rc
, rc
);
1499 nsAutoString arrayTypeSchemaURI
;
1500 nsAutoString arrayTypeSchemaName
;
1501 if (!schemaArrayType
) {
1502 switch (arrayNativeType
) {
1503 case nsIDataType::VTYPE_INTERFACE
: // In a variant, an interface is a struct, but here it is any
1504 case nsIDataType::VTYPE_INTERFACE_IS
:
1505 arrayTypeSchemaName
= gSOAPStrings
->kAnyTypeSchemaType
;
1506 arrayTypeSchemaURI
= gSOAPStrings
->kXSURI
;
1508 default: // Everything else can be interpreted correctly
1509 GetNativeType(arrayNativeType
, arrayTypeSchemaURI
, arrayTypeSchemaName
);
1511 nsCOMPtr
<nsISchemaCollection
> collection
;
1513 aEncoding
->GetSchemaCollection(getter_AddRefs(collection
));
1514 NS_ENSURE_SUCCESS(rc
, rc
);
1516 rc
= collection
->GetType(arrayTypeSchemaName
,
1517 arrayTypeSchemaName
,
1518 getter_AddRefs(schemaArrayType
));
1519 // if (NS_FAILED(rc)) return rc;
1522 rc
= schemaArrayType
->GetTargetNamespace(arrayTypeSchemaURI
);
1523 NS_ENSURE_SUCCESS(rc
, rc
);
1525 rc
= schemaArrayType
->GetName(arrayTypeSchemaName
);
1526 NS_ENSURE_SUCCESS(rc
, rc
);
1528 rc
= EncodeSimpleValue(aEncoding
, gSOAPStrings
->kEmpty
,
1530 aName
, aSchemaType
, aDestination
, aReturnValue
);
1531 NS_ENSURE_SUCCESS(rc
, rc
);
1533 // This needs a real live interpretation of the type.
1537 nsSOAPUtils::MakeNamespacePrefix(aEncoding
,*aReturnValue
,arrayTypeSchemaURI
,value
);
1538 value
.Append(gSOAPStrings
->kQualifiedSeparator
);
1539 value
.Append(arrayTypeSchemaName
);
1540 value
.Append(PRUnichar('['));
1541 for (i
= 0; i
< dimensionCount
; i
++) {
1543 value
.Append(PRUnichar(','));
1544 char* ptr
= PR_smprintf("%d", dimensionSizes
[i
]);
1545 AppendUTF8toUTF16(ptr
, value
);
1546 PR_smprintf_free(ptr
);
1548 value
.Append(PRUnichar(']'));
1549 nsAutoString encURI
;
1550 rc
= aEncoding
->GetExternalSchemaURI(gSOAPStrings
->kSOAPEncURI
,encURI
);
1551 NS_ENSURE_SUCCESS(rc
, rc
);
1553 rc
= (*aReturnValue
)->SetAttributeNS(encURI
, gSOAPStrings
->kSOAPArrayTypeAttribute
, value
);
1554 NS_ENSURE_SUCCESS(rc
, rc
);
1557 // For efficiency, we should perform encoder lookup once here.
1559 return EncodeArray(aEncoding
, aSource
, schemaArrayType
, aAttachments
, *aReturnValue
, dimensionCount
, dimensionSizes
);
1565 nsStringEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1566 nsIVariant
* aSource
,
1567 const nsAString
& aNamespaceURI
,
1568 const nsAString
& aName
,
1569 nsISchemaType
* aSchemaType
,
1570 nsISOAPAttachments
* aAttachments
,
1571 nsIDOMElement
* aDestination
,
1572 nsIDOMElement
* *aReturnValue
)
1574 NS_ENSURE_ARG_POINTER(aEncoding
);
1575 NS_ENSURE_ARG_POINTER(aDestination
);
1576 NS_ENSURE_ARG_POINTER(aReturnValue
);
1577 *aReturnValue
= nsnull
;
1580 rc
= aSource
->GetAsAString(value
);
1581 NS_ENSURE_SUCCESS(rc
, rc
);
1583 return EncodeSimpleValue(aEncoding
, value
,
1584 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1591 nsBooleanEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1592 nsIVariant
* aSource
,
1593 const nsAString
& aNamespaceURI
,
1594 const nsAString
& aName
,
1595 nsISchemaType
* aSchemaType
,
1596 nsISOAPAttachments
* aAttachments
,
1597 nsIDOMElement
* aDestination
,
1598 nsIDOMElement
* *aReturnValue
)
1600 NS_ENSURE_ARG_POINTER(aEncoding
);
1601 NS_ENSURE_ARG_POINTER(aDestination
);
1602 NS_ENSURE_ARG_POINTER(aReturnValue
);
1603 *aReturnValue
= nsnull
;
1606 rc
= aSource
->GetAsBool(&b
);
1607 NS_ENSURE_SUCCESS(rc
, rc
);
1609 return EncodeSimpleValue(aEncoding
, b
? gSOAPStrings
->kTrueA
: gSOAPStrings
->kFalseA
,
1610 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1617 nsDoubleEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1618 nsIVariant
* aSource
,
1619 const nsAString
& aNamespaceURI
,
1620 const nsAString
& aName
,
1621 nsISchemaType
* aSchemaType
,
1622 nsISOAPAttachments
* aAttachments
,
1623 nsIDOMElement
* aDestination
,
1624 nsIDOMElement
* *aReturnValue
)
1626 NS_ENSURE_ARG_POINTER(aEncoding
);
1627 NS_ENSURE_ARG_POINTER(aDestination
);
1628 NS_ENSURE_ARG_POINTER(aReturnValue
);
1629 *aReturnValue
= nsnull
;
1632 rc
= aSource
->GetAsDouble(&f
); // Check that double works.
1633 NS_ENSURE_SUCCESS(rc
, rc
);
1636 // Note that AppendFloat actually takes a double, so this is ok.
1637 value
.AppendFloat(f
);
1638 return EncodeSimpleValue(aEncoding
, value
,
1639 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1646 nsFloatEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1647 nsIVariant
* aSource
,
1648 const nsAString
& aNamespaceURI
,
1649 const nsAString
& aName
,
1650 nsISchemaType
* aSchemaType
,
1651 nsISOAPAttachments
* aAttachments
,
1652 nsIDOMElement
* aDestination
,
1653 nsIDOMElement
* *aReturnValue
)
1655 NS_ENSURE_ARG_POINTER(aEncoding
);
1656 NS_ENSURE_ARG_POINTER(aDestination
);
1657 NS_ENSURE_ARG_POINTER(aReturnValue
);
1658 *aReturnValue
= nsnull
;
1661 rc
= aSource
->GetAsFloat(&f
); // Check that float works.
1662 NS_ENSURE_SUCCESS(rc
, rc
);
1665 value
.AppendFloat(f
);
1666 return EncodeSimpleValue(aEncoding
, value
,
1667 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1674 nsLongEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1675 nsIVariant
* aSource
,
1676 const nsAString
& aNamespaceURI
,
1677 const nsAString
& aName
,
1678 nsISchemaType
* aSchemaType
,
1679 nsISOAPAttachments
* aAttachments
,
1680 nsIDOMElement
* aDestination
,
1681 nsIDOMElement
* *aReturnValue
)
1683 NS_ENSURE_ARG_POINTER(aEncoding
);
1684 NS_ENSURE_ARG_POINTER(aDestination
);
1685 NS_ENSURE_ARG_POINTER(aReturnValue
);
1686 *aReturnValue
= nsnull
;
1689 rc
= aSource
->GetAsInt64(&f
); // Get as a long number.
1690 NS_ENSURE_SUCCESS(rc
, rc
);
1692 char *ptr
= PR_smprintf("%lld", f
);
1694 return NS_ERROR_OUT_OF_MEMORY
;
1696 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
1697 PR_smprintf_free(ptr
);
1698 return EncodeSimpleValue(aEncoding
, value
,
1699 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1706 nsIntEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1707 nsIVariant
* aSource
,
1708 const nsAString
& aNamespaceURI
,
1709 const nsAString
& aName
,
1710 nsISchemaType
* aSchemaType
,
1711 nsISOAPAttachments
* aAttachments
,
1712 nsIDOMElement
* aDestination
,
1713 nsIDOMElement
* *aReturnValue
)
1715 NS_ENSURE_ARG_POINTER(aEncoding
);
1716 NS_ENSURE_ARG_POINTER(aDestination
);
1717 NS_ENSURE_ARG_POINTER(aReturnValue
);
1718 *aReturnValue
= nsnull
;
1721 rc
= aSource
->GetAsInt32(&f
); // Get as a long number.
1722 NS_ENSURE_SUCCESS(rc
, rc
);
1724 char *ptr
= PR_smprintf("%d", f
);
1726 return NS_ERROR_OUT_OF_MEMORY
;
1728 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
1729 PR_smprintf_free(ptr
);
1730 return EncodeSimpleValue(aEncoding
, value
,
1731 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1738 nsShortEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1739 nsIVariant
* aSource
,
1740 const nsAString
& aNamespaceURI
,
1741 const nsAString
& aName
,
1742 nsISchemaType
* aSchemaType
,
1743 nsISOAPAttachments
* aAttachments
,
1744 nsIDOMElement
* aDestination
,
1745 nsIDOMElement
* *aReturnValue
)
1747 NS_ENSURE_ARG_POINTER(aEncoding
);
1748 NS_ENSURE_ARG_POINTER(aDestination
);
1749 NS_ENSURE_ARG_POINTER(aReturnValue
);
1750 *aReturnValue
= nsnull
;
1753 rc
= aSource
->GetAsInt16(&f
); // Get as a long number.
1754 NS_ENSURE_SUCCESS(rc
, rc
);
1756 char *ptr
= PR_smprintf("%d", (PRInt32
) f
);
1758 return NS_ERROR_OUT_OF_MEMORY
;
1760 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
1761 PR_smprintf_free(ptr
);
1762 return EncodeSimpleValue(aEncoding
, value
,
1763 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1770 nsByteEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1771 nsIVariant
* aSource
,
1772 const nsAString
& aNamespaceURI
,
1773 const nsAString
& aName
,
1774 nsISchemaType
* aSchemaType
,
1775 nsISOAPAttachments
* aAttachments
,
1776 nsIDOMElement
* aDestination
,
1777 nsIDOMElement
* *aReturnValue
)
1779 NS_ENSURE_ARG_POINTER(aEncoding
);
1780 NS_ENSURE_ARG_POINTER(aDestination
);
1781 NS_ENSURE_ARG_POINTER(aReturnValue
);
1782 *aReturnValue
= nsnull
;
1785 rc
= aSource
->GetAsInt8(&f
); // Get as a long number.
1786 NS_ENSURE_SUCCESS(rc
, rc
);
1788 char *ptr
= PR_smprintf("%d", (PRInt32
) (signed char) f
);
1790 return NS_ERROR_OUT_OF_MEMORY
;
1792 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
1793 PR_smprintf_free(ptr
);
1794 return EncodeSimpleValue(aEncoding
, value
,
1795 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1802 nsUnsignedLongEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1803 nsIVariant
* aSource
,
1804 const nsAString
& aNamespaceURI
,
1805 const nsAString
& aName
,
1806 nsISchemaType
* aSchemaType
,
1807 nsISOAPAttachments
* aAttachments
,
1808 nsIDOMElement
* aDestination
,
1809 nsIDOMElement
* *aReturnValue
)
1811 NS_ENSURE_ARG_POINTER(aEncoding
);
1812 NS_ENSURE_ARG_POINTER(aDestination
);
1813 NS_ENSURE_ARG_POINTER(aReturnValue
);
1814 *aReturnValue
= nsnull
;
1817 rc
= aSource
->GetAsUint64(&f
); // Get as a long number.
1818 NS_ENSURE_SUCCESS(rc
, rc
);
1820 char *ptr
= PR_smprintf("%llu", f
);
1822 return NS_ERROR_OUT_OF_MEMORY
;
1824 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
1825 PR_smprintf_free(ptr
);
1826 return EncodeSimpleValue(aEncoding
, value
,
1827 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1834 nsUnsignedIntEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1835 nsIVariant
* aSource
,
1836 const nsAString
& aNamespaceURI
,
1837 const nsAString
& aName
,
1838 nsISchemaType
* aSchemaType
,
1839 nsISOAPAttachments
* aAttachments
,
1840 nsIDOMElement
* aDestination
,
1841 nsIDOMElement
* *aReturnValue
)
1843 NS_ENSURE_ARG_POINTER(aEncoding
);
1844 NS_ENSURE_ARG_POINTER(aDestination
);
1845 NS_ENSURE_ARG_POINTER(aReturnValue
);
1846 *aReturnValue
= nsnull
;
1849 rc
= aSource
->GetAsUint32(&f
); // Get as a long number.
1850 NS_ENSURE_SUCCESS(rc
, rc
);
1852 char *ptr
= PR_smprintf("%u", f
);
1854 return NS_ERROR_OUT_OF_MEMORY
;
1856 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
1857 PR_smprintf_free(ptr
);
1858 return EncodeSimpleValue(aEncoding
, value
,
1859 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1864 nsBase64BinaryEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1865 nsIVariant
* aSource
,
1866 const nsAString
& aNamespaceURI
,
1867 const nsAString
& aName
,
1868 nsISchemaType
* aSchemaType
,
1869 nsISOAPAttachments
* aAttachments
,
1870 nsIDOMElement
* aDestination
,
1871 nsIDOMElement
* *aReturnValue
)
1873 NS_ENSURE_ARG_POINTER(aSource
);
1874 NS_ENSURE_ARG_POINTER(aEncoding
);
1875 NS_ENSURE_ARG_POINTER(aDestination
);
1876 NS_ENSURE_ARG_POINTER(aReturnValue
);
1878 *aReturnValue
= nsnull
;
1881 nsresult rv
= aSource
->GetDataType(&typeValue
);
1882 NS_ENSURE_SUCCESS(rv
, rv
);
1884 if (typeValue
!= nsIDataType::VTYPE_ARRAY
) {
1885 return NS_ERROR_FAILURE
;
1891 rv
= aSource
->GetAsArray(&typeValue
, &iid
, &count
, &array
);
1892 NS_ENSURE_SUCCESS(rv
, rv
);
1894 if (typeValue
!= nsIDataType::VTYPE_UINT8
) {
1895 return NS_ERROR_FAILURE
;
1898 char* encodedVal
= PL_Base64Encode(static_cast<char*>(array
), count
, nsnull
);
1900 return NS_ERROR_FAILURE
;
1902 nsAdoptingCString
encodedString(encodedVal
);
1904 nsAutoString name
, ns
;
1905 if (aName
.IsEmpty()) {
1906 // If we don't have a name, we pick soapenc:base64Binary.
1907 rv
= aEncoding
->GetStyleURI(ns
);
1908 NS_ENSURE_SUCCESS(rv
, rv
);
1909 name
.Append(gSOAPStrings
->kBase64BinarySchemaType
);
1913 // ns remains empty. This is ok.
1916 nsCOMPtr
<nsIDOMDocument
> document
;
1917 rv
= aDestination
->GetOwnerDocument(getter_AddRefs(document
));
1918 NS_ENSURE_SUCCESS(rv
, rv
);
1920 nsCOMPtr
<nsIDOMElement
> element
;
1921 rv
= document
->CreateElementNS(ns
, name
, getter_AddRefs(element
));
1922 NS_ENSURE_SUCCESS(rv
, rv
);
1924 nsCOMPtr
<nsIDOMNode
> ignore
;
1925 rv
= aDestination
->AppendChild(element
, getter_AddRefs(ignore
));
1926 NS_ENSURE_SUCCESS(rv
, rv
);
1929 nsAutoString typeName
, typeNS
;
1930 rv
= aSchemaType
->GetName(typeName
);
1931 NS_ENSURE_SUCCESS(rv
, rv
);
1932 rv
= aSchemaType
->GetTargetNamespace(typeNS
);
1933 NS_ENSURE_SUCCESS(rv
, rv
);
1936 rv
= nsSOAPUtils::MakeNamespacePrefix(nsnull
, element
, typeNS
, qname
);
1937 NS_ENSURE_SUCCESS(rv
, rv
);
1939 qname
.Append(gSOAPStrings
->kQualifiedSeparator
+ typeName
);
1942 rv
= aEncoding
->GetExternalSchemaURI(gSOAPStrings
->kXSIURI
, ns
);
1943 NS_ENSURE_SUCCESS(rv
, rv
);
1945 rv
= element
->SetAttributeNS(ns
, gSOAPStrings
->kXSITypeAttribute
, qname
);
1946 NS_ENSURE_SUCCESS(rv
, rv
);
1949 nsCOMPtr
<nsIDOMText
> text
;
1950 rv
= document
->CreateTextNode(NS_ConvertASCIItoUTF16(encodedString
),
1951 getter_AddRefs(text
));
1952 NS_ENSURE_SUCCESS(rv
, rv
);
1954 rv
= element
->AppendChild(text
, getter_AddRefs(ignore
));
1955 NS_ENSURE_SUCCESS(rv
, rv
);
1957 NS_ADDREF(*aReturnValue
= element
);
1965 nsUnsignedShortEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1966 nsIVariant
* aSource
,
1967 const nsAString
& aNamespaceURI
,
1968 const nsAString
& aName
,
1969 nsISchemaType
* aSchemaType
,
1970 nsISOAPAttachments
* aAttachments
,
1971 nsIDOMElement
* aDestination
,
1972 nsIDOMElement
* *aReturnValue
)
1974 NS_ENSURE_ARG_POINTER(aEncoding
);
1975 NS_ENSURE_ARG_POINTER(aDestination
);
1976 NS_ENSURE_ARG_POINTER(aReturnValue
);
1977 *aReturnValue
= nsnull
;
1980 rc
= aSource
->GetAsUint16(&f
); // Get as a long number.
1981 NS_ENSURE_SUCCESS(rc
, rc
);
1983 char *ptr
= PR_smprintf("%u", (PRUint32
) f
);
1985 return NS_ERROR_OUT_OF_MEMORY
;
1987 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
1988 PR_smprintf_free(ptr
);
1989 return EncodeSimpleValue(aEncoding
, value
,
1990 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
1997 nsUnsignedByteEncoder::Encode(nsISOAPEncoding
* aEncoding
,
1998 nsIVariant
* aSource
,
1999 const nsAString
& aNamespaceURI
,
2000 const nsAString
& aName
,
2001 nsISchemaType
* aSchemaType
,
2002 nsISOAPAttachments
* aAttachments
,
2003 nsIDOMElement
* aDestination
,
2004 nsIDOMElement
* *aReturnValue
)
2006 NS_ENSURE_ARG_POINTER(aEncoding
);
2007 NS_ENSURE_ARG_POINTER(aDestination
);
2008 NS_ENSURE_ARG_POINTER(aReturnValue
);
2009 *aReturnValue
= nsnull
;
2012 rc
= aSource
->GetAsUint8(&f
); // Get as a long number.
2013 NS_ENSURE_SUCCESS(rc
, rc
);
2015 char *ptr
= PR_smprintf("%u", (PRUint32
) f
);
2017 return NS_ERROR_OUT_OF_MEMORY
;
2019 CopyASCIItoUTF16(nsDependentCString(ptr
), value
);
2020 PR_smprintf_free(ptr
);
2021 return EncodeSimpleValue(aEncoding
, value
,
2022 aNamespaceURI
, aName
, aSchemaType
, aDestination
,
2027 nsDefaultEncoder::Decode(nsISOAPEncoding
* aEncoding
,
2028 nsIDOMElement
* aSource
,
2029 nsISchemaType
* aSchemaType
,
2030 nsISOAPAttachments
* aAttachments
,
2031 nsIVariant
** aResult
)
2033 NS_ENSURE_ARG_POINTER(aEncoding
);
2034 NS_ENSURE_ARG_POINTER(aSource
);
2035 NS_ENSURE_ARG_POINTER(aResult
);
2037 nsCOMPtr
<nsISOAPEncoding
> encoding
= aEncoding
; // First, handle encoding redesignation, if any
2038 nsCOMPtr
<nsISchemaType
> schemaType
;
2039 nsresult rv
= GetExplicitType(aEncoding
, aSource
, getter_AddRefs(schemaType
));
2041 if (NS_FAILED(rv
) || !schemaType
) {
2042 schemaType
= aSchemaType
;
2046 nsCOMPtr
<nsIDOMAttr
> enc
;
2049 GetAttributeNodeNS(*gSOAPStrings
->kSOAPEnvURI
[mSOAPVersion
],
2050 gSOAPStrings
->kEncodingStyleAttribute
,
2051 getter_AddRefs(enc
));
2052 NS_ENSURE_SUCCESS(rv
, rv
);
2055 nsAutoString oldstyle
;
2056 rv
= encoding
->GetStyleURI(oldstyle
);
2057 NS_ENSURE_SUCCESS(rv
, rv
);
2060 rv
= enc
->GetNodeValue(style
);
2061 NS_ENSURE_SUCCESS(rv
, rv
);
2063 if (!style
.Equals(oldstyle
)) {
2064 nsCOMPtr
<nsISOAPEncoding
> newencoding
;
2065 rv
= encoding
->GetAssociatedEncoding(style
, PR_FALSE
,
2066 getter_AddRefs(newencoding
));
2067 NS_ENSURE_SUCCESS(rv
, rv
);
2070 return newencoding
->Decode(aSource
, aSchemaType
, aAttachments
, aResult
);
2076 // Handle xsi:null="true|1" and xsi:nil="true|1"
2078 nsAutoString nullstr
;
2079 if (nsSOAPUtils::GetAttribute(aEncoding
,
2081 gSOAPStrings
->kXSIURI
,
2082 gSOAPStrings
->kNull
,
2084 nsSOAPUtils::GetAttribute(aEncoding
,
2086 gSOAPStrings
->kXSIURI
,
2090 return HandleNull(aEncoding
,
2099 nsCOMPtr
<nsISchemaType
> type
= schemaType
;
2100 nsCOMPtr
<nsISOAPDecoder
> decoder
; // All that comes out of this block is decoder, type, and some checks.
2101 { // Look up type element and schema attribute, if possible
2102 nsCOMPtr
<nsISchemaType
> subType
;
2103 nsCOMPtr
<nsISchemaCollection
> collection
;
2105 aEncoding
->GetSchemaCollection(getter_AddRefs(collection
));
2106 NS_ENSURE_SUCCESS(rc
, rc
);
2111 rc
= aSource
->GetNamespaceURI(name
);
2112 NS_ENSURE_SUCCESS(rc
, rc
);
2114 rc
= aEncoding
->GetInternalSchemaURI(name
, ns
);
2115 NS_ENSURE_SUCCESS(rc
, rc
);
2117 rc
= aSource
->GetLocalName(name
);
2118 NS_ENSURE_SUCCESS(rc
, rc
);
2120 nsCOMPtr
<nsISchemaElement
> element
;
2121 rc
= collection
->GetElement(name
, ns
, getter_AddRefs(element
));
2122 // if (NS_FAILED(rc)) return rc;
2124 rc
= element
->GetType(getter_AddRefs(subType
));
2125 NS_ENSURE_SUCCESS(rc
, rc
);
2127 nsAutoString internal
;
2128 rc
= aEncoding
->GetInternalSchemaURI(ns
, internal
);
2129 NS_ENSURE_SUCCESS(rc
, rc
);
2131 if (internal
.Equals(gSOAPStrings
->kSOAPEncURI
)) { // Last-ditch hack to get undeclared types from SOAP namespace
2132 if (name
.Equals(gSOAPStrings
->kArraySOAPType
) ||
2133 name
.Equals(gSOAPStrings
->kStructSOAPType
)) { // This should not be needed if schema has these declarations
2134 rc
= collection
->GetType(name
, internal
, getter_AddRefs(subType
));
2136 rc
= collection
->GetType(name
,
2137 gSOAPStrings
->kXSURI
,
2138 getter_AddRefs(subType
));
2141 // if (NS_FAILED(rc)) return rc;
2146 nsCOMPtr
<nsISchemaType
> subsubType
;
2147 nsAutoString explicitType
;
2148 if (nsSOAPUtils::GetAttribute(aEncoding
, aSource
, gSOAPStrings
->kXSIURI
,
2149 gSOAPStrings
->kXSITypeAttribute
,
2151 rc
= nsSOAPUtils::GetNamespaceURI(aEncoding
, aSource
, explicitType
, ns
);
2152 NS_ENSURE_SUCCESS(rc
, rc
);
2154 rc
= nsSOAPUtils::GetLocalName(explicitType
, name
);
2155 NS_ENSURE_SUCCESS(rc
, rc
);
2157 rc
= collection
->GetType(name
, ns
, getter_AddRefs(subsubType
));
2158 // if (NS_FAILED(rc)) return rc;
2161 subsubType
= subType
;
2163 if (subsubType
) { // Loop up the hierarchy, to check and look for decoders
2165 nsCOMPtr
<nsISchemaType
> lookupType
= subsubType
;
2167 if (lookupType
== subType
) { // Tick off the located super classes
2170 if (lookupType
== type
) { // Tick off the located super classes
2174 nsAutoString schemaType
;
2175 nsAutoString schemaURI
;
2176 nsresult rc
= lookupType
->GetName(schemaType
);
2177 NS_ENSURE_SUCCESS(rc
, rc
);
2179 rc
= lookupType
->GetTargetNamespace(schemaURI
);
2180 NS_ENSURE_SUCCESS(rc
, rc
);
2182 nsAutoString encodingKey
;
2183 SOAPEncodingKey(schemaURI
, schemaType
, encodingKey
);
2184 rc
= aEncoding
->GetDecoder(encodingKey
, getter_AddRefs(decoder
));
2185 NS_ENSURE_SUCCESS(rc
, rc
);
2187 nsCOMPtr
<nsISchemaType
> supertype
;
2188 rc
= GetSupertype(aEncoding
, lookupType
, getter_AddRefs(supertype
));
2189 NS_ENSURE_SUCCESS(rc
, rc
);
2191 lookupType
= supertype
;
2192 } while (lookupType
);
2201 subsubType
= subType
;
2206 PRBool simple
= PR_TRUE
;
2208 nsresult rc
= HasSimpleValue(type
, &simple
);
2209 NS_ENSURE_SUCCESS(rc
, rc
);
2212 nsCOMPtr
<nsIDOMElement
> child
;
2213 nsSOAPUtils::GetFirstChildElement(aSource
, getter_AddRefs(child
));
2216 nsAutoString decodingKey
;
2218 SOAPEncodingKey(gSOAPStrings
->kSOAPEncURI
,
2219 gSOAPStrings
->kStructSOAPType
, decodingKey
);
2221 SOAPEncodingKey(gSOAPStrings
->kXSURI
,
2222 gSOAPStrings
->kAnySimpleTypeSchemaType
, decodingKey
);
2225 aEncoding
->GetDecoder(decodingKey
, getter_AddRefs(decoder
));
2226 NS_ENSURE_SUCCESS(rc
, rc
);
2229 return decoder
->Decode(aEncoding
, aSource
, type
, aAttachments
,
2233 return SOAP_EXCEPTION(NS_ERROR_NOT_IMPLEMENTED
,
2234 "SOAP_NO_DECODER_FOR_TYPE",
2235 "The default decoder finds no decoder for specific type");
2239 nsAnyTypeEncoder::Decode(nsISOAPEncoding
* aEncoding
,
2240 nsIDOMElement
* aSource
,
2241 nsISchemaType
* aSchemaType
,
2242 nsISOAPAttachments
* aAttachments
,
2243 nsIVariant
** _retval
)
2245 NS_ENSURE_ARG_POINTER(aEncoding
);
2246 NS_ENSURE_ARG_POINTER(aSource
);
2247 NS_ENSURE_ARG_POINTER(_retval
);
2249 PRBool simple
= PR_TRUE
;
2251 nsresult rc
= HasSimpleValue(aSchemaType
, &simple
);
2252 NS_ENSURE_SUCCESS(rc
, rc
);
2255 nsCOMPtr
<nsIDOMElement
> child
;
2256 nsSOAPUtils::GetFirstChildElement(aSource
, getter_AddRefs(child
));
2259 nsAutoString decodingKey
;
2261 SOAPEncodingKey(gSOAPStrings
->kSOAPEncURI
,
2262 gSOAPStrings
->kStructSOAPType
, decodingKey
);
2264 SOAPEncodingKey(gSOAPStrings
->kXSURI
,
2265 gSOAPStrings
->kAnySimpleTypeSchemaType
, decodingKey
);
2267 nsCOMPtr
<nsISOAPDecoder
> decoder
;
2269 aEncoding
->GetDecoder(decodingKey
, getter_AddRefs(decoder
));
2270 NS_ENSURE_SUCCESS(rc
, rc
);
2273 return decoder
->Decode(aEncoding
, aSource
,
2274 aSchemaType
, aAttachments
, _retval
);
2277 return SOAP_EXCEPTION(NS_ERROR_NOT_IMPLEMENTED
,"SOAP_NO_DECODER_FOR_TYPE","The any type decoder finds no decoder for specific element");
2281 * Decode struct particle. If particle is model group this method
2282 * call itself recursively for each particle contained in the model group.
2284 * @param aEncoding SOAP encoding to be used (in).
2285 * @param aElement DOM element representing particle to be decoded (in).
2286 * @param aParticle Schema particle that should declare struct particle (in).
2287 * @param aAttachments SOAP attachments (in).
2288 * @param aDestination Property bag where to stored decoded particle (in).
2289 * @param aResult Remaining DOM element to be decoded, left over one (out).
2291 static nsresult
DecodeStructParticle(nsISOAPEncoding
* aEncoding
,
2292 nsIDOMElement
* aElement
,
2293 nsISchemaParticle
* aParticle
,
2294 nsISOAPAttachments
* aAttachments
,
2295 nsISOAPPropertyBagMutator
* aDestination
,
2296 nsIDOMElement
** aResult
)
2302 rc
= aParticle
->GetMinOccurs(&minOccurs
);
2303 NS_ENSURE_SUCCESS(rc
, rc
);
2306 rc
= aParticle
->GetMaxOccurs(&maxOccurs
);
2307 NS_ENSURE_SUCCESS(rc
, rc
);
2309 PRUint16 particleType
;
2310 rc
= aParticle
->GetParticleType(&particleType
);
2311 NS_ENSURE_SUCCESS(rc
, rc
);
2313 switch(particleType
) {
2314 case nsISchemaParticle::PARTICLE_TYPE_ELEMENT
: {
2315 if (maxOccurs
> 1) { // Todo: Try to make this thing work as an array?
2316 return NS_ERROR_NOT_AVAILABLE
; // For now, we just try something else if we can (recoverable)
2318 nsCOMPtr
<nsISchemaElement
> element
= do_QueryInterface(aParticle
);
2320 rc
= element
->GetTargetNamespace(name
);
2321 NS_ENSURE_SUCCESS(rc
, rc
);
2323 if (!name
.IsEmpty()) {
2324 rc
= NS_ERROR_NOT_AVAILABLE
; // No known way to use namespace qualification in struct
2327 rc
= element
->GetName(name
);
2328 NS_ENSURE_SUCCESS(rc
, rc
);
2331 if (aElement
) { // Permits aElement to be null and fail recoverably
2333 rc
= aElement
->GetNamespaceURI(ename
);
2334 NS_ENSURE_SUCCESS(rc
, rc
);
2336 if (ename
.IsEmpty()) { // Only get an ename if there is an empty namespaceURI
2337 rc
= aElement
->GetLocalName(ename
);
2338 NS_ENSURE_SUCCESS(rc
, rc
);
2341 if (!ename
.Equals(name
))
2342 rc
= NS_ERROR_NOT_AVAILABLE
; // The element must be a declaration of the next element
2344 if (NS_SUCCEEDED(rc
)) {
2345 nsCOMPtr
<nsISchemaType
> type
;
2346 rc
= element
->GetType(getter_AddRefs(type
));
2347 NS_ENSURE_SUCCESS(rc
, rc
);
2349 nsCOMPtr
<nsIVariant
> value
;
2350 rc
= aEncoding
->Decode(aElement
, type
, aAttachments
, getter_AddRefs(value
));
2351 NS_ENSURE_SUCCESS(rc
, rc
);
2354 nsCOMPtr
<nsIWritableVariant
> nullVariant(do_CreateInstance("@mozilla.org/variant;1"));
2356 nullVariant
->SetAsISupports(nsnull
);
2357 value
= do_QueryInterface(nullVariant
);
2360 rc
= aDestination
->AddProperty(name
, value
);
2361 NS_ENSURE_SUCCESS(rc
, rc
);
2363 nsSOAPUtils::GetNextSiblingElement(aElement
, aResult
);
2365 if (minOccurs
== 0 && rc
== NS_ERROR_NOT_AVAILABLE
) { // If we failed recoverably, but we were permitted to, then return success
2366 NS_IF_ADDREF(*aResult
= aElement
);
2371 case nsISchemaParticle::PARTICLE_TYPE_MODEL_GROUP
:
2373 if (maxOccurs
> 1) { // Todo: Try to make this thing work as an array?
2374 return NS_ERROR_NOT_AVAILABLE
; // For now, we just try something else if we can (recoverable)
2376 nsCOMPtr
<nsISchemaModelGroup
> modelGroup
= do_QueryInterface(aParticle
);
2377 PRUint16 compositor
;
2378 rc
= modelGroup
->GetCompositor(&compositor
);
2379 NS_ENSURE_SUCCESS(rc
, rc
);
2381 PRUint32 particleCount
;
2382 rc
= modelGroup
->GetParticleCount(&particleCount
);
2383 NS_ENSURE_SUCCESS(rc
, rc
);
2386 if (compositor
== nsISchemaModelGroup::COMPOSITOR_ALL
) { // This handles out-of-order appearances.
2387 // Use hashtable to be able to get corresponding particle
2388 // according SOAP element name not according schema order
2389 // as a <all> model group is used
2390 nsInterfaceHashtable
<nsStringHashKey
,nsISchemaParticle
> groupParticles
;
2391 groupParticles
.Init(particleCount
);
2392 nsCOMPtr
<nsISchemaParticle
> child
;
2393 PRBool mangled
= PR_FALSE
;
2395 // Build schema particle mappings from model group
2396 for (i
= 0; i
< particleCount
; i
++) {
2397 rc
= modelGroup
->GetParticle(i
, getter_AddRefs(child
));
2398 NS_ENSURE_SUCCESS(rc
, rc
);
2400 nsAutoString particleName
;
2401 rc
= child
->GetName(particleName
);
2402 NS_ENSURE_SUCCESS(rc
, rc
);
2404 rc
= groupParticles
.Put(particleName
, child
);
2405 NS_ENSURE_SUCCESS(rc
, rc
);
2408 nsCOMPtr
<nsIDOMElement
> next
= aElement
;
2412 Since we are an xsd:all, the order of elements in the schema type
2413 does not matter. So we go element by element in the XML fragment
2414 we are decoding. We loop through all schema particles defined for
2415 this type until we find one that DecodeStructParticle succeeds on.
2416 DecodeStructParticle returns |after| with is what is left to decode,
2417 so we can figure if the decoding succeeded by checking if |after|
2418 is not equal to the element we are decoding (|next|).
2420 We track if we couldn't decode using the |decoded| boolean. If we
2421 exit the particle walking for loop and |decoded| is false, we bail.
2423 XXX: what if we get out of the while loop, and |all| still has
2424 particles? Should we walk them and see if any are minOccurs > 0
2425 and return an error?
2428 // loop as long as we have something to decode.
2432 // we cycle through the schema particles
2433 for (i
= 0; i
< particleCount
; i
++) {
2435 rc
= next
->GetTagName(name
);
2436 NS_ENSURE_SUCCESS(rc
, rc
);
2438 // Get schema particle according SOAP element
2439 groupParticles
.Get(name
, getter_AddRefs(child
));
2441 if (NS_FAILED(rc
) || !child
) {
2443 nsAutoString
msg(NS_LITERAL_STRING("::DecodeStructParticle: "));
2444 msg
.AppendLiteral("Cannot find schema particle for \"");
2446 msg
.AppendLiteral("\"");
2447 NS_ERROR(NS_ConvertUTF16toUTF8(msg
).get());
2451 nsCOMPtr
<nsIDOMElement
> after
;
2452 rc
= DecodeStructParticle(aEncoding
, next
, child
, aAttachments
, aDestination
, getter_AddRefs(after
));
2454 // DecodeStructParticle returns success even if decoding didn't
2455 // work. So we check if after != next to see if it did succeed.
2456 if (NS_SUCCEEDED(rc
) && after
!= next
) {
2460 groupParticles
.Remove(name
);
2466 // This detects ambiguous model (non-deterministic choice which
2467 // fails after succeeding on first)
2468 if ((mangled
&& rc
== NS_ERROR_NOT_AVAILABLE
) || !decoded
) {
2469 rc
= SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,"SOAP_AMBIGUOUS_DECODING","Cannot proceed due to ambiguity or error in content model");
2470 // Error is not considered recoverable due to partially-created output.
2473 // if we failed to decode after the for loop, abort.
2474 if (NS_FAILED(rc
) || !decoded
)
2478 // if *aResult is not null, then caller knows we couldn't decode
2480 if (NS_SUCCEEDED(rc
)) {
2481 NS_IF_ADDREF(*aResult
= next
);
2482 } else if (minOccurs
== 0 && rc
== NS_ERROR_NOT_AVAILABLE
) {
2483 // If we succeeded or failed recoverably, but we were permitted to,
2484 // then return success
2485 NS_IF_ADDREF(*aResult
= aElement
);
2489 else { // This handles sequences and choices.
2490 nsCOMPtr
<nsIDOMElement
> next
= aElement
;
2491 for (i
= 0; i
< particleCount
; i
++) {
2492 nsCOMPtr
<nsISchemaParticle
> child
;
2493 rc
= modelGroup
->GetParticle(i
, getter_AddRefs(child
));
2494 NS_ENSURE_SUCCESS(rc
, rc
);
2496 nsCOMPtr
<nsIDOMElement
> after
;
2497 rc
= DecodeStructParticle(aEncoding
, next
, child
, aAttachments
, aDestination
, getter_AddRefs(after
));
2498 if (NS_SUCCEEDED(rc
)) {
2501 if (compositor
== nsISchemaModelGroup::COMPOSITOR_CHOICE
) {
2502 if (rc
== NS_ERROR_NOT_AVAILABLE
) {
2506 if (NS_SUCCEEDED(rc
)) {
2507 NS_IF_ADDREF(*aResult
= next
);
2512 else if (i
> 0 && rc
== NS_ERROR_NOT_AVAILABLE
) { // This detects ambiguous model (non-deterministic choice which fails after succeeding on first)
2513 rc
= SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,"SOAP_AMBIGUOUS_DECODING","Cannot proceed due to ambiguity or error in content model");
2514 // Error is not considered recoverable due to partially-created output.
2519 if (compositor
== nsISchemaModelGroup::COMPOSITOR_CHOICE
)
2520 rc
= NS_ERROR_NOT_AVAILABLE
;
2521 if (NS_SUCCEEDED(rc
)) {
2522 NS_IF_ADDREF(*aResult
= next
);
2524 if (minOccurs
== 0 && rc
== NS_ERROR_NOT_AVAILABLE
) { // If we succeeded or failed recoverably, but we were permitted to, then return success
2525 NS_IF_ADDREF(*aResult
= aElement
);
2529 return rc
; // Return status
2531 case nsISchemaParticle::PARTICLE_TYPE_ANY
:
2532 // No model available here (we may wish to handle strict versus lazy, but what does that mean with only local accessor names)
2538 nsCOMPtr
<nsIDOMElement
> child
= aElement
;
2541 nsAutoString namespaceURI
;
2542 nsCOMPtr
<nsIVariant
>value
;
2543 rc
= child
->GetLocalName(name
);
2544 NS_ENSURE_SUCCESS(rc
, rc
);
2546 rc
= child
->GetNamespaceURI(namespaceURI
);
2547 NS_ENSURE_SUCCESS(rc
, rc
);
2549 if (!namespaceURI
.IsEmpty()) { // If we ever figure out what to do with namespaces, get an internal one
2550 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
2551 "SOAP_GLOBAL_ACCESSOR",
2552 "Decoded struct contained global accessor, which does not map well into a property name.");
2554 rc
= aEncoding
->Decode(child
, nsnull
, aAttachments
, getter_AddRefs(value
));
2555 NS_ENSURE_SUCCESS(rc
, rc
);
2558 nsCOMPtr
<nsIWritableVariant
> nullVariant(do_CreateInstance("@mozilla.org/variant;1"));
2560 nullVariant
->SetAsISupports(nsnull
);
2561 value
= do_QueryInterface(nullVariant
);
2564 rc
= aDestination
->AddProperty(name
, value
);
2565 NS_ENSURE_SUCCESS(rc
, rc
);
2567 nsCOMPtr
<nsIDOMElement
> nextchild
;
2568 nsSOAPUtils::GetNextSiblingElement(child
, getter_AddRefs(nextchild
));
2576 nsStructEncoder::Decode(nsISOAPEncoding
* aEncoding
,
2577 nsIDOMElement
* aSource
,
2578 nsISchemaType
* aSchemaType
,
2579 nsISOAPAttachments
* aAttachments
,
2580 nsIVariant
** aResult
)
2582 NS_ENSURE_ARG_POINTER(aEncoding
);
2583 NS_ENSURE_ARG_POINTER(aSource
);
2584 NS_ENSURE_ARG_POINTER(aResult
);
2587 nsCOMPtr
<nsISOAPPropertyBagMutator
> mutator
= do_CreateInstance(NS_SOAPPROPERTYBAGMUTATOR_CONTRACTID
, &rc
);
2588 NS_ENSURE_SUCCESS(rc
, rc
);
2590 nsCOMPtr
<nsISchemaModelGroup
> modelGroup
;
2592 nsCOMPtr
<nsISchemaComplexType
> ctype
= do_QueryInterface(aSchemaType
);
2594 rc
= ctype
->GetModelGroup(getter_AddRefs(modelGroup
));
2595 NS_ENSURE_SUCCESS(rc
, rc
);
2598 nsCOMPtr
<nsIDOMElement
> child
;
2599 nsSOAPUtils::GetFirstChildElement(aSource
, getter_AddRefs(child
));
2600 nsCOMPtr
<nsIDOMElement
> result
;
2601 rc
= DecodeStructParticle(aEncoding
, child
, modelGroup
, aAttachments
, mutator
, getter_AddRefs(result
));
2602 if (NS_SUCCEEDED(rc
) // If there were elements left over, then we failed to decode everything.
2604 rc
= SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,"SOAP_LEFTOVERS","Decoded struct contained extra items not mentioned in the content model.");
2605 NS_ENSURE_SUCCESS(rc
, rc
);
2607 nsCOMPtr
<nsIPropertyBag
> bag
;
2608 rc
= mutator
->GetPropertyBag(getter_AddRefs(bag
));
2609 NS_ENSURE_SUCCESS(rc
, rc
);
2611 nsCOMPtr
<nsIWritableVariant
> p
=
2612 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
2613 NS_ENSURE_SUCCESS(rc
, rc
);
2615 rc
= p
->SetAsInterface(NS_GET_IID(nsIPropertyBag
), bag
);
2616 NS_ENSURE_SUCCESS(rc
, rc
);
2618 NS_ADDREF(*aResult
= p
);
2623 nsAnySimpleTypeEncoder::Decode(nsISOAPEncoding
* aEncoding
,
2624 nsIDOMElement
* aSource
,
2625 nsISchemaType
* aSchemaType
,
2626 nsISOAPAttachments
* aAttachments
,
2627 nsIVariant
** aResult
)
2629 NS_ENSURE_ARG_POINTER(aEncoding
);
2630 NS_ENSURE_ARG_POINTER(aSource
);
2631 NS_ENSURE_ARG_POINTER(aResult
);
2634 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
2635 NS_ENSURE_SUCCESS(rc
, rc
);
2637 nsCOMPtr
<nsIWritableVariant
> p
=
2638 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
2639 NS_ENSURE_SUCCESS(rc
, rc
);
2641 rc
= p
->SetAsAString(value
);
2642 NS_ENSURE_SUCCESS(rc
, rc
);
2644 NS_ADDREF(*aResult
= p
);
2649 * Extract multiple bracketted numbers from the end of
2650 * the string and return the string with the number
2651 * removed or return the original string and -1. Either
2652 * the number of dimensions or the size of any particular
2653 * dimension can be returned as -1. An over-all 0
2654 * means that either there were no dimensions or there
2655 * was a fundamental problem interpreting it. A
2656 * -1 on any particular size of a dimension means that
2657 * that particular size was not available or was not
2658 * interpretable. That may be a recoverable error
2659 * if the values represented a size, because we can
2660 * manually scan the array, but that shouldbe fatal
2661 * if specifying a position. In these cases, the
2662 * bracketted values are removed.
2664 static PRUint32
DecodeArrayDimensions(const nsAString
& src
, PRInt32
* aDimensionSizes
, nsAString
& dst
)
2667 nsReadingIterator
< PRUnichar
> i1
;
2668 nsReadingIterator
< PRUnichar
> i2
;
2669 src
.BeginReading(i1
);
2671 if (src
.IsEmpty()) return 0;
2672 while (i1
!= i2
// Loop past white space
2673 && *(--i2
) <= ' ') // In XML, all valid characters <= space are the only whitespace
2675 if (*i2
!= ']') { // In this case, not an array dimension
2676 PRInt32 len
= Distance(i1
, i2
) - 1; // This is the size to truncate to at the end.
2677 dst
= Substring(src
, 0, len
); // Truncate the string.
2678 return 0; // Eliminated white space.
2681 PRInt32 dimensionCount
= 1; // Counting the dimensions
2682 for (;;) { // First look for the matching bracket from reverse and commas.
2683 if (i1
== i2
) { // No matching bracket.
2686 PRUnichar c
= *(--i2
);
2687 if (c
== '[') { // Matching bracket found!
2696 nsReadingIterator
< PRUnichar
> i3
= i2
++; // Cover any extra white space
2697 while (i1
!= i3
) { // Loop past white space
2698 if (*(--i3
) > ' ') { // In XML, all valid characters <= space are the only whitespace
2703 len
= Distance(i1
, i3
); // Length remaining in string after operation
2706 if (dimensionCount
> MAX_ARRAY_DIMENSIONS
) { // Completely ignore it if too many dimensions.
2712 while (*(--i2
) != ']') // Find end bracket again
2715 dimensionCount
= 0; // Start with first dimension.
2716 aDimensionSizes
[dimensionCount
] = -1;
2717 PRBool finished
= PR_FALSE
; // Disallow space within numbers
2720 PRUnichar c
= *(i1
++);
2721 if (c
< '0' || c
> '9') {
2722 // There may be slightly more to do here if alternative radixes are supported.
2723 if (c
<= ' ') { // In XML, all valid characters <= space are the only whitespace
2724 if (aDimensionSizes
[dimensionCount
] >= 0) {
2728 else if (c
== ',') { // Introducing new dimension
2729 aDimensionSizes
[++dimensionCount
] = -1; // Restarting it at -1
2730 finished
= PR_FALSE
;
2733 return 0; // Unrecognized character
2736 return 0; // Numbers not allowed after white space
2738 if (aDimensionSizes
[dimensionCount
] == -1)
2739 aDimensionSizes
[dimensionCount
] = 0;
2740 if (aDimensionSizes
[dimensionCount
] < 214748364) {
2741 aDimensionSizes
[dimensionCount
] = aDimensionSizes
[dimensionCount
] * 10 + c
- '0';
2744 return 0; // Number got too big.
2748 dst
= Substring(src
, 0, len
); // Truncate the string.
2749 return dimensionCount
+ 1; // Return the number of dimensions
2753 * Extract multiple bracketted numbers from the end of
2754 * the string and reconcile with a passed-in set of
2755 * dimensions, computing the offset in the array.
2756 * Presumes that the caller already knows the dimensions
2757 * fit into 32-bit signed integer, due to computing
2758 * total size of array.
2760 * If there is extra garbage within the
2761 * Any blank or unreadable dimensions or extra garbage
2762 * within the string result in a return of -1, which is
2763 * bad wherever a position string was interpreted.
2765 static PRInt32
DecodeArrayPosition(const nsAString
& src
, PRUint32 aDimensionCount
, PRInt32
* aDimensionSizes
)
2767 PRInt32 pos
[MAX_ARRAY_DIMENSIONS
];
2768 nsAutoString leftover
;
2769 PRUint32 i
= DecodeArrayDimensions(src
, pos
, leftover
);
2770 if (i
!= aDimensionCount
|| !leftover
.IsEmpty()) {
2771 // Easy cases where something went wrong
2776 PRInt32 next
= pos
[i
];
2777 if (next
== -1 || next
>= aDimensionSizes
[i
])
2779 result
= result
+ next
;
2780 if (++i
< aDimensionCount
) // Multiply for next round.
2781 result
= result
* aDimensionSizes
[i
];
2789 * Expand the resulting array out into a nice pseudo-multi-dimensional
2790 * array. We trust that the caller guaranteed aDimensionCount >= 1 and that
2791 * the other sizes are reasonable (or they couldn't pass us a resultant
2792 * array). * The result is produced recursively as:
2793 * an array [of arrays [...]] of the specified type.
2794 * Variants are used to embed arrays inside of * arrays.
2796 static nsresult
CreateArray(nsIWritableVariant
* aResult
, PRUint16 aType
, const nsIID
* aIID
,
2797 PRUint32 aDimensionCount
, PRInt32
* aDimensionSizes
, PRUint32 aSizeof
, PRUint8
* aArray
)
2799 if (aSizeof
== 0) { // Variants do not support construction of null-sized arrays
2800 return aResult
->SetAsEmptyArray();
2802 if (aDimensionCount
> 1) { // We cannot reuse variants because they are kept by resulting array
2803 PRInt32 count
= aDimensionSizes
[0];
2804 PRUint32 size
= aSizeof
/ count
;
2806 nsIVariant
** a
= new nsIVariant
*[count
]; // Create variant array.
2808 return NS_ERROR_OUT_OF_MEMORY
;
2810 nsresult rc
= NS_OK
;
2812 for (i
= 0; i
< count
; i
++) {
2813 nsCOMPtr
<nsIWritableVariant
> v
= do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
2816 nsresult rc
= CreateArray(v
, aType
, aIID
, aDimensionCount
- 1, aDimensionSizes
+ 1,
2820 NS_ADDREF(a
[i
] = v
); // Addref for array reference
2823 if (NS_SUCCEEDED(rc
)) {
2824 rc
= aResult
->SetAsArray(nsIDataType::VTYPE_INTERFACE_IS
,&NS_GET_IID(nsIVariant
),count
,a
);
2826 for (i
= 0; i
< count
; i
++) { // Release variants for array
2827 nsIVariant
* v
= a
[i
];
2835 return aResult
->SetAsArray(aType
,aIID
,aDimensionSizes
[0],aArray
);
2839 // Incomplete -- becomes very complex due to variant arrays
2841 nsArrayEncoder::Decode(nsISOAPEncoding
* aEncoding
,
2842 nsIDOMElement
* aSource
,
2843 nsISchemaType
* aSchemaType
,
2844 nsISOAPAttachments
* aAttachments
,
2845 nsIVariant
** aResult
)
2847 NS_ENSURE_ARG_POINTER(aEncoding
);
2848 NS_ENSURE_ARG_POINTER(aSource
);
2849 NS_ENSURE_ARG_POINTER(aResult
);
2853 nsCOMPtr
<nsISchemaType
> schemaArrayType
;
2855 PRUint32 dimensionCount
= 0; // Number of dimensions
2856 PRInt32 dimensionSizes
[MAX_ARRAY_DIMENSIONS
];
2862 nsresult rc
= aSchemaType
->GetSchemaType(&type
);
2863 NS_ENSURE_SUCCESS(rc
, rc
);
2865 if (type
== nsISchemaType::SCHEMA_TYPE_COMPLEX
) {
2866 nsCOMPtr
<nsISchemaComplexType
> ct
= do_QueryInterface(aSchemaType
);
2867 nsresult rc
= ct
->GetArrayDimension(&dimensionCount
);
2868 NS_ENSURE_SUCCESS(rc
, rc
);
2870 rc
= ct
->GetArrayType(getter_AddRefs(schemaArrayType
));
2871 NS_ENSURE_SUCCESS(rc
, rc
);
2874 if (nsSOAPUtils::GetAttribute(aEncoding
, aSource
, gSOAPStrings
->kSOAPEncURI
,
2875 gSOAPStrings
->kSOAPArrayTypeAttribute
, value
)) {
2877 PRUint32 n
= DecodeArrayDimensions(value
, dimensionSizes
, dst
);
2879 if (dimensionCount
== n
|| dimensionCount
== 0) {
2883 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
2884 "SOAP_WRONG_ARRAY_SIZE",
2885 "Array declares different number of dimensions from what schema declared.");
2886 // We cannot get conflicting information from schema and content.
2891 if (dimensionCount
> 0) {
2892 PRInt64 tot
= 1; // Collect in 64 bits, just to make sure it fits
2893 for (i
= 0; i
< dimensionCount
; i
++) {
2894 PRInt32 next
= dimensionSizes
[i
];
2900 if (tot
> 0x7fffffff) {
2901 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
2902 "SOAP_ARRAY_TOO_BIG",
2903 "When decoding an object as an array, the total count of items exceeded maximum.");
2906 size
= (PRInt32
)tot
;
2909 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
2910 "SOAP_ARRAY_UNDECLARED",
2911 "Array type did not end with proper array dimensions.");
2912 // A dimension count must be part of the arrayType
2915 // The array type is either array if ']' or other specific type.
2916 nsCOMPtr
<nsISchemaCollection
> collection
;
2917 rc
= aEncoding
->GetSchemaCollection(getter_AddRefs(collection
));
2918 NS_ENSURE_SUCCESS(rc
, rc
);
2920 if (value
.Last() ==']') {
2921 ns
.Assign(gSOAPStrings
->kSOAPEncURI
);
2922 name
.Assign(gSOAPStrings
->kArraySOAPType
);
2925 rc
= nsSOAPUtils::GetNamespaceURI(aEncoding
, aSource
, value
, ns
);
2926 NS_ENSURE_SUCCESS(rc
, rc
);
2928 rc
= nsSOAPUtils::GetLocalName(value
, name
);
2929 NS_ENSURE_SUCCESS(rc
, rc
);
2931 nsCOMPtr
<nsISchemaType
> subtype
;
2932 rc
= collection
->GetType(name
, ns
, getter_AddRefs(subtype
));
2933 // if (NS_FAILED(rc)) return rc;
2935 subtype
= schemaArrayType
;
2937 if (subtype
) { // Loop up the hierarchy, to ensure suitability of subtype
2938 if (schemaArrayType
) {
2939 nsCOMPtr
<nsISchemaType
> lookupType
= subtype
;
2941 if (lookupType
== schemaArrayType
) { // Tick off the located super classes
2942 schemaArrayType
= nsnull
;
2945 nsCOMPtr
<nsISchemaType
> supertype
;
2946 rc
= GetSupertype(aEncoding
, lookupType
, getter_AddRefs(supertype
));
2947 NS_ENSURE_SUCCESS(rc
, rc
);
2949 lookupType
= supertype
;
2950 } while (lookupType
);
2952 if (schemaArrayType
) // If the proper subclass relationship didn't exist, then error return.
2953 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
2955 "The type of the array must be a subclass of the declared type.");
2956 schemaArrayType
= subtype
; // If they did, then we now have a new, better type.
2959 PRUint32 offset
; // Computing offset trickier, because size may be unspecified.
2960 if (nsSOAPUtils::GetAttribute(aEncoding
, aSource
, gSOAPStrings
->kSOAPEncURI
,
2961 gSOAPStrings
->kSOAPArrayOffsetAttribute
, value
)) {
2962 PRInt32 pos
[MAX_ARRAY_DIMENSIONS
];
2963 nsAutoString leftover
;
2964 offset
= DecodeArrayDimensions(value
, pos
, leftover
);
2965 if (dimensionCount
== 0)
2966 dimensionCount
= offset
;
2968 offset
!= dimensionCount
||
2969 !leftover
.IsEmpty()) {
2970 // We have to understand this or report an error
2971 // But the offset does not need to be understood
2972 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
2973 "SOAP_ARRAY_OFFSET",
2974 "Illegal value given for array offset");
2976 PRInt32 old0
= dimensionSizes
[0];
2977 if (dimensionSizes
[0] == -1) {
2978 // It is OK to have a offset where dimension 0 is unspecified
2979 dimensionSizes
[0] = 2147483647;
2983 PRInt64 next
= pos
[i
];
2984 if (next
== -1 || next
>= dimensionSizes
[i
]) {
2985 rc
= NS_ERROR_ILLEGAL_VALUE
;
2988 next
= (offset
+ next
);
2989 if (next
> 2147483647) {
2990 rc
= NS_ERROR_ILLEGAL_VALUE
;
2993 offset
= (PRInt32
)next
;
2994 if (++i
< dimensionCount
) {
2995 next
= offset
* dimensionSizes
[i
];
2996 if (next
> 2147483647) {
2997 rc
= NS_ERROR_ILLEGAL_VALUE
;
3000 offset
= (PRInt32
)next
;
3008 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3009 "SOAP_ARRAY_OFFSET",
3010 "Illegal value given for array offset");
3011 dimensionSizes
[0] = old0
;
3016 if (size
== -1) { // If no known size, we have to go through and pre-count.
3017 nsCOMPtr
<nsIDOMElement
> child
;
3018 nsSOAPUtils::GetFirstChildElement(aSource
, getter_AddRefs(child
));
3019 PRInt32 pp
[MAX_ARRAY_DIMENSIONS
];
3020 if (dimensionCount
!= 0) {
3021 for (i
= dimensionCount
; i
-- != 0;) {
3026 PRInt32 next
= offset
;
3029 if (nsSOAPUtils::GetAttribute(aEncoding
, aSource
, gSOAPStrings
->kSOAPEncURI
,
3030 gSOAPStrings
->kSOAPArrayPositionAttribute
, pos
)) {
3031 // if array item contains an explicit 'position' attribute use it
3032 nsAutoString leftover
;
3033 PRInt32 inc
[MAX_ARRAY_DIMENSIONS
];
3034 i
= DecodeArrayDimensions(pos
, inc
, leftover
);
3036 !leftover
.IsEmpty() ||
3037 (dimensionCount
!=0 && dimensionCount
!= i
)) {
3038 // We have to understand this or report an error
3039 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3040 "SOAP_ARRAY_POSITION",
3041 "Illegal value given for array element position");
3043 if (dimensionCount
== 0) {
3044 dimensionCount
= i
; // If we never had dimension count before, we do now.
3045 for (i
= dimensionCount
; i
-- != 0;) {
3049 for (i
= 0; i
< dimensionCount
; i
++) {
3051 if (n
== -1) { // Positions must be concrete
3052 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3053 "SOAP_ARRAY_POSITION",
3054 "Illegal value given for array element position");
3061 // No explicit 'position' attribute
3062 next
++; // Keep tabs on how many unnumbered items there are
3065 nsCOMPtr
<nsIDOMElement
> nextchild
;
3066 nsSOAPUtils::GetNextSiblingElement(child
, getter_AddRefs(nextchild
));
3069 if (dimensionCount
== 0) { // If unknown or 1 dimension, unpositioned entries can help
3072 dimensionSizes
[0] = next
;
3074 else if (dimensionCount
== 1
3077 dimensionSizes
[0] = next
;
3079 PRInt64 tot
= 1; // Collect in 64 bits, just to make sure it fits
3080 for (i
= 0; i
< dimensionCount
; i
++) {
3081 PRInt32 next
= dimensionSizes
[i
];
3082 if (next
== -1) { // Only derive those with no other declaration
3083 dimensionSizes
[i
] = next
= pp
[i
];
3086 if (tot
> 0x7fffffff) {
3087 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3088 "SOAP_ARRAY_TOO_BIG",
3089 "When decoding an object as an array, the total count of items exceeded maximum.");
3092 size
= (PRInt32
)tot
; // At last, we know the dimensions of the array.
3095 // After considerable work, we may have a schema type and a size.
3097 nsCOMPtr
<nsIWritableVariant
> result
= do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
3100 #define DECODE_ARRAY(XPType, VTYPE, iid, Convert, Free) \
3101 XPType* a = new XPType[size];\
3103 return NS_ERROR_OUT_OF_MEMORY;\
3104 for (si = 0; si < size; si++) a[si] = 0;\
3105 nsCOMPtr<nsIDOMElement> child;\
3106 nsSOAPUtils::GetFirstChildElement(aSource, getter_AddRefs(child));\
3107 PRUint32 next = offset;\
3111 if (nsSOAPUtils::GetAttribute(aEncoding, aSource, gSOAPStrings->kSOAPEncURI,\
3112 gSOAPStrings->kSOAPArrayPositionAttribute, pos)) {\
3113 p = DecodeArrayPosition(pos, dimensionCount, dimensionSizes);\
3115 rc = NS_ERROR_ILLEGAL_VALUE;\
3122 if (p >= size || a[p]) {\
3123 rc = NS_ERROR_ILLEGAL_VALUE;\
3126 nsCOMPtr<nsIVariant> v;\
3128 rc = aEncoding->Decode(child, schemaArrayType, aAttachments, getter_AddRefs(v));\
3133 nsCOMPtr<nsIDOMElement> next;\
3134 nsSOAPUtils::GetNextSiblingElement(child, getter_AddRefs(next));\
3137 if (NS_SUCCEEDED(rc)) {\
3138 rc = CreateArray(result, nsIDataType::VTYPE_##VTYPE,iid,dimensionCount,dimensionSizes,sizeof(a[0])*size,(PRUint8*)a);\
3143 #define DECODE_SIMPLE_ARRAY(XPType, VType, VTYPE) \
3144 DECODE_ARRAY(XPType, VTYPE, nsnull, rc = v->GetAs##VType(a + p);if(NS_FAILED(rc))break;,do{}while(0);)
3146 if (rc
== NS_ERROR_ILLEGAL_VALUE
)
3147 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3148 "SOAP_ARRAY_POSITIONS",
3149 "Colliding array positions discovered.");
3150 NS_ENSURE_SUCCESS(rc
, rc
);
3152 PRBool unhandled
= PR_FALSE
;
3153 if (ns
.Equals(gSOAPStrings
->kXSURI
)) {
3154 if (name
.Equals(gSOAPStrings
->kStringSchemaType
)) {
3155 DECODE_ARRAY(PRUnichar
*,WCHAR_STR
,nsnull
,rc
= v
->GetAsWString(a
+ p
);if(NS_FAILED(rc
))break;,
3156 for (si
= 0; si
< size
; si
++) nsMemory::Free(a
[si
]););
3157 } else if (name
.Equals(gSOAPStrings
->kBooleanSchemaType
)) {
3158 DECODE_SIMPLE_ARRAY(PRBool
,Bool
,BOOL
);
3159 } else if (name
.Equals(gSOAPStrings
->kFloatSchemaType
)) {
3160 DECODE_SIMPLE_ARRAY(float,Float
,FLOAT
);
3161 } else if (name
.Equals(gSOAPStrings
->kDoubleSchemaType
)) {
3162 DECODE_SIMPLE_ARRAY(double,Double
,DOUBLE
);
3163 } else if (name
.Equals(gSOAPStrings
->kLongSchemaType
)) {
3164 DECODE_SIMPLE_ARRAY(PRInt64
,Int64
,INT64
);
3165 } else if (name
.Equals(gSOAPStrings
->kIntSchemaType
)) {
3166 DECODE_SIMPLE_ARRAY(PRInt32
,Int32
,INT32
);
3167 } else if (name
.Equals(gSOAPStrings
->kShortSchemaType
)) {
3168 DECODE_SIMPLE_ARRAY(PRInt16
,Int16
,INT16
);
3169 } else if (name
.Equals(gSOAPStrings
->kByteSchemaType
)) {
3170 DECODE_SIMPLE_ARRAY(PRUint8
,Int8
,INT8
);
3171 } else if (name
.Equals(gSOAPStrings
->kUnsignedLongSchemaType
)) {
3172 DECODE_SIMPLE_ARRAY(PRUint64
,Uint64
,UINT64
);
3173 } else if (name
.Equals(gSOAPStrings
->kUnsignedIntSchemaType
)) {
3174 DECODE_SIMPLE_ARRAY(PRUint32
,Uint32
,UINT32
);
3175 } else if (name
.Equals(gSOAPStrings
->kUnsignedShortSchemaType
)) {
3176 DECODE_SIMPLE_ARRAY(PRUint16
,Uint16
,UINT16
);
3177 } else if (name
.Equals(gSOAPStrings
->kUnsignedByteSchemaType
)) {
3178 DECODE_SIMPLE_ARRAY(PRUint8
,Uint8
,UINT8
);
3180 unhandled
= PR_TRUE
;
3183 unhandled
= PR_TRUE
;
3185 if (unhandled
) { // Handle all the other cases
3186 DECODE_ARRAY(nsIVariant
*,INTERFACE_IS
,&NS_GET_IID(nsIVariant
),
3187 NS_ADDREF(a
[p
] = v
);,
3188 for (si
= 0; si
< size
; si
++) NS_IF_RELEASE(a
[si
]););
3190 NS_ENSURE_SUCCESS(rc
, rc
);
3192 NS_ADDREF(*aResult
= result
);
3197 nsStringEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3198 nsIDOMElement
* aSource
,
3199 nsISchemaType
* aSchemaType
,
3200 nsISOAPAttachments
* aAttachments
,
3201 nsIVariant
** aResult
)
3203 NS_ENSURE_ARG_POINTER(aEncoding
);
3204 NS_ENSURE_ARG_POINTER(aSource
);
3205 NS_ENSURE_ARG_POINTER(aResult
);
3208 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3209 NS_ENSURE_SUCCESS(rc
, rc
);
3211 nsCOMPtr
<nsIWritableVariant
> p
=
3212 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
3213 NS_ENSURE_SUCCESS(rc
, rc
);
3215 rc
= p
->SetAsAString(value
);
3216 NS_ENSURE_SUCCESS(rc
, rc
);
3218 NS_ADDREF(*aResult
= p
);
3223 nsBooleanEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3224 nsIDOMElement
* aSource
,
3225 nsISchemaType
* aSchemaType
,
3226 nsISOAPAttachments
* aAttachments
,
3227 nsIVariant
** aResult
)
3229 NS_ENSURE_ARG_POINTER(aEncoding
);
3230 NS_ENSURE_ARG_POINTER(aSource
);
3231 NS_ENSURE_ARG_POINTER(aResult
);
3234 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3235 NS_ENSURE_SUCCESS(rc
, rc
);
3238 if (value
.Equals(gSOAPStrings
->kTrue
) ||
3239 value
.Equals(gSOAPStrings
->kTrueA
)) {
3241 } else if (value
.Equals(gSOAPStrings
->kFalse
) ||
3242 value
.Equals(gSOAPStrings
->kFalseA
)) {
3245 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3246 "SOAP_ILLEGAL_BOOLEAN",
3247 "Illegal value discovered for boolean");
3250 nsCOMPtr
<nsIWritableVariant
> p
=
3251 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3252 NS_ENSURE_SUCCESS(rc
, rc
);
3256 NS_ADDREF(*aResult
= p
);
3261 nsDoubleEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3262 nsIDOMElement
* aSource
,
3263 nsISchemaType
* aSchemaType
,
3264 nsISOAPAttachments
* aAttachments
,
3265 nsIVariant
** aResult
)
3267 NS_ENSURE_ARG_POINTER(aEncoding
);
3268 NS_ENSURE_ARG_POINTER(aSource
);
3269 NS_ENSURE_ARG_POINTER(aResult
);
3272 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3273 NS_ENSURE_SUCCESS(rc
, rc
);
3277 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %lf %n", &f
, &n
);
3278 if (r
== 0 || n
< value
.Length()) {
3279 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3280 "SOAP_ILLEGAL_DOUBLE",
3281 "Illegal value discovered for double");
3284 nsCOMPtr
<nsIWritableVariant
> p
=
3285 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rc
);
3286 NS_ENSURE_SUCCESS(rc
, rc
);
3290 NS_ADDREF(*aResult
= p
);
3295 nsFloatEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3296 nsIDOMElement
* aSource
,
3297 nsISchemaType
* aSchemaType
,
3298 nsISOAPAttachments
* aAttachments
,
3299 nsIVariant
** aResult
)
3301 NS_ENSURE_ARG_POINTER(aEncoding
);
3302 NS_ENSURE_ARG_POINTER(aSource
);
3303 NS_ENSURE_ARG_POINTER(aResult
);
3306 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3307 NS_ENSURE_SUCCESS(rc
, rc
);
3311 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %f %n", &f
, &n
);
3312 if (r
== 0 || n
< value
.Length()) {
3313 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3314 "SOAP_ILLEGAL_FLOAT",
3315 "Illegal value discovered for float");
3318 nsCOMPtr
<nsIWritableVariant
> p
=
3319 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3320 NS_ENSURE_SUCCESS(rc
, rc
);
3324 NS_ADDREF(*aResult
= p
);
3329 nsLongEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3330 nsIDOMElement
* aSource
,
3331 nsISchemaType
* aSchemaType
,
3332 nsISOAPAttachments
* aAttachments
,
3333 nsIVariant
** aResult
)
3335 NS_ENSURE_ARG_POINTER(aEncoding
);
3336 NS_ENSURE_ARG_POINTER(aSource
);
3337 NS_ENSURE_ARG_POINTER(aResult
);
3340 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3341 NS_ENSURE_SUCCESS(rc
, rc
);
3345 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %lld %n", &f
, &n
);
3346 if (r
== 0 || n
< value
.Length()) {
3347 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3348 "SOAP_ILLEGAL_LONG",
3349 "Illegal value discovered for long");
3352 nsCOMPtr
<nsIWritableVariant
> p
=
3353 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3354 NS_ENSURE_SUCCESS(rc
, rc
);
3358 NS_ADDREF(*aResult
= p
);
3363 nsIntEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3364 nsIDOMElement
* aSource
,
3365 nsISchemaType
* aSchemaType
,
3366 nsISOAPAttachments
* aAttachments
,
3367 nsIVariant
** aResult
)
3369 NS_ENSURE_ARG_POINTER(aEncoding
);
3370 NS_ENSURE_ARG_POINTER(aSource
);
3371 NS_ENSURE_ARG_POINTER(aResult
);
3374 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3375 NS_ENSURE_SUCCESS(rc
, rc
);
3379 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %ld %n", &f
, &n
);
3380 if (r
== 0 || n
< value
.Length()) {
3381 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3383 "Illegal value discovered for int");
3386 nsCOMPtr
<nsIWritableVariant
> p
=
3387 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3388 NS_ENSURE_SUCCESS(rc
, rc
);
3391 NS_ADDREF(*aResult
= p
);
3396 nsShortEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3397 nsIDOMElement
* aSource
,
3398 nsISchemaType
* aSchemaType
,
3399 nsISOAPAttachments
* aAttachments
,
3400 nsIVariant
** aResult
)
3402 NS_ENSURE_ARG_POINTER(aEncoding
);
3403 NS_ENSURE_ARG_POINTER(aSource
);
3404 NS_ENSURE_ARG_POINTER(aResult
);
3407 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3408 NS_ENSURE_SUCCESS(rc
, rc
);
3412 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %hd %n", &f
, &n
);
3413 if (r
== 0 || n
< value
.Length()) {
3414 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3415 "SOAP_ILLEGAL_SHORT",
3416 "Illegal value discovered for short");
3419 nsCOMPtr
<nsIWritableVariant
> p
=
3420 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3421 NS_ENSURE_SUCCESS(rc
, rc
);
3424 NS_ADDREF(*aResult
= p
);
3429 nsByteEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3430 nsIDOMElement
* aSource
,
3431 nsISchemaType
* aSchemaType
,
3432 nsISOAPAttachments
* aAttachments
,
3433 nsIVariant
** aResult
)
3435 NS_ENSURE_ARG_POINTER(aEncoding
);
3436 NS_ENSURE_ARG_POINTER(aSource
);
3437 NS_ENSURE_ARG_POINTER(aResult
);
3440 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3441 NS_ENSURE_SUCCESS(rc
, rc
);
3445 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %hd %n", &f
, &n
);
3446 if (r
== 0 || n
< value
.Length() || f
< -128 || f
> 127) {
3447 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3448 "SOAP_ILLEGAL_BYTE",
3449 "Illegal value discovered for byte");
3452 nsCOMPtr
<nsIWritableVariant
> p
=
3453 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3454 NS_ENSURE_SUCCESS(rc
, rc
);
3456 p
->SetAsInt8((PRUint8
) f
);
3457 NS_ADDREF(*aResult
= p
);
3462 nsUnsignedLongEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3463 nsIDOMElement
* aSource
,
3464 nsISchemaType
* aSchemaType
,
3465 nsISOAPAttachments
* aAttachments
,
3466 nsIVariant
** aResult
)
3468 NS_ENSURE_ARG_POINTER(aEncoding
);
3469 NS_ENSURE_ARG_POINTER(aSource
);
3470 NS_ENSURE_ARG_POINTER(aResult
);
3473 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3474 NS_ENSURE_SUCCESS(rc
, rc
);
3478 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %llu %n", &f
, &n
);
3479 if (r
== 0 || n
< value
.Length()) {
3480 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3481 "SOAP_ILLEGAL_ULONG",
3482 "Illegal value discovered for unsigned long");
3485 nsCOMPtr
<nsIWritableVariant
> p
=
3486 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3487 NS_ENSURE_SUCCESS(rc
, rc
);
3490 NS_ADDREF(*aResult
= p
);
3495 nsUnsignedIntEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3496 nsIDOMElement
* aSource
,
3497 nsISchemaType
* aSchemaType
,
3498 nsISOAPAttachments
* aAttachments
,
3499 nsIVariant
** aResult
)
3501 NS_ENSURE_ARG_POINTER(aEncoding
);
3502 NS_ENSURE_ARG_POINTER(aSource
);
3503 NS_ENSURE_ARG_POINTER(aResult
);
3506 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3507 NS_ENSURE_SUCCESS(rc
, rc
);
3511 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %lu %n", &f
, &n
);
3512 if (r
== 0 || n
< value
.Length()) {
3513 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3514 "SOAP_ILLEGAL_UINT",
3515 "Illegal value discovered for unsigned int");
3518 nsCOMPtr
<nsIWritableVariant
> p
=
3519 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3520 NS_ENSURE_SUCCESS(rc
, rc
);
3523 NS_ADDREF(*aResult
= p
);
3528 nsBase64BinaryEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3529 nsIDOMElement
* aSource
,
3530 nsISchemaType
* aSchemaType
,
3531 nsISOAPAttachments
* aAttachments
,
3532 nsIVariant
** aResult
)
3534 NS_ENSURE_ARG_POINTER(aEncoding
);
3535 NS_ENSURE_ARG_POINTER(aSource
);
3536 NS_ENSURE_ARG_POINTER(aResult
);
3540 nsresult rv
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3541 NS_ENSURE_SUCCESS(rv
, rv
);
3543 NS_LossyConvertUTF16toASCII
valueStr(value
);
3544 valueStr
.StripChars(" \n\r\t");
3546 char* decodedVal
= PL_Base64Decode(valueStr
.get(), valueStr
.Length(), nsnull
);
3548 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3549 "SOAP_ILLEGAL_BASE64",
3550 "Data cannot be decoded as Base64");
3553 nsCOMPtr
<nsIWritableVariant
> p
=
3554 do_CreateInstance(NS_VARIANT_CONTRACTID
, &rv
);
3556 if (NS_SUCCEEDED(rv
)) {
3558 rv
= p
->SetAsArray(nsIDataType::VTYPE_UINT8
, nsnull
,
3559 strlen(decodedVal
), decodedVal
);
3562 PR_Free(decodedVal
);
3563 NS_ENSURE_SUCCESS(rv
, rv
);
3565 NS_ADDREF(*aResult
= p
);
3570 nsUnsignedShortEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3571 nsIDOMElement
* aSource
,
3572 nsISchemaType
* aSchemaType
,
3573 nsISOAPAttachments
* aAttachments
,
3574 nsIVariant
** aResult
)
3576 NS_ENSURE_ARG_POINTER(aEncoding
);
3577 NS_ENSURE_ARG_POINTER(aSource
);
3578 NS_ENSURE_ARG_POINTER(aResult
);
3581 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3582 NS_ENSURE_SUCCESS(rc
, rc
);
3586 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %hu %n", &f
, &n
);
3587 if (r
== 0 || n
< value
.Length()) {
3588 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3589 "SOAP_ILLEGAL_USHORT",
3590 "Illegal value discovered for unsigned short");
3593 nsCOMPtr
<nsIWritableVariant
> p
=
3594 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3595 NS_ENSURE_SUCCESS(rc
, rc
);
3598 NS_ADDREF(*aResult
= p
);
3603 nsUnsignedByteEncoder::Decode(nsISOAPEncoding
* aEncoding
,
3604 nsIDOMElement
* aSource
,
3605 nsISchemaType
* aSchemaType
,
3606 nsISOAPAttachments
* aAttachments
,
3607 nsIVariant
** aResult
)
3609 NS_ENSURE_ARG_POINTER(aEncoding
);
3610 NS_ENSURE_ARG_POINTER(aSource
);
3611 NS_ENSURE_ARG_POINTER(aResult
);
3614 nsresult rc
= nsSOAPUtils::GetElementTextContent(aSource
, value
);
3615 NS_ENSURE_SUCCESS(rc
, rc
);
3619 PRInt32 r
= PR_sscanf(NS_ConvertUTF16toUTF8(value
).get(), " %hu %n", &f
, &n
);
3620 if (r
== 0 || n
< value
.Length() || f
> 255) {
3621 return SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE
,
3622 "SOAP_ILLEGAL_UBYTE",
3623 "Illegal value discovered for unsigned byte");
3626 nsCOMPtr
<nsIWritableVariant
> p
=
3627 do_CreateInstance(NS_VARIANT_CONTRACTID
,&rc
);
3628 NS_ENSURE_SUCCESS(rc
, rc
);
3630 p
->SetAsUint8((PRUint8
) f
);
3631 NS_ADDREF(*aResult
= p
);