initial load of upstream version 1.06.32
[xmlrpc-c] / src / xmlrpc_data.c
1 /* Copyright information is at end of file */
2
3 #include "xmlrpc_config.h"
4
5 #include <stddef.h>
6 #include <stdlib.h>
7 #include <stdarg.h>
8 #include <string.h>
9
10 #include "bool.h"
11 #include "mallocvar.h"
12
13 #include "xmlrpc-c/base.h"
14 #include "xmlrpc-c/base_int.h"
15
16
17
18 static void
19 destroyValue(xmlrpc_value * const valueP) {
20
21     /* First, we need to destroy this value's contents, if any. */
22     switch (valueP->_type) {
23     case XMLRPC_TYPE_INT:
24         break;
25         
26     case XMLRPC_TYPE_BOOL:
27         break;
28
29     case XMLRPC_TYPE_DOUBLE:
30         break;
31
32     case XMLRPC_TYPE_DATETIME:
33         xmlrpc_mem_block_clean(&valueP->_block);
34         break;
35
36     case XMLRPC_TYPE_STRING:
37         if (valueP->_wcs_block)
38             xmlrpc_mem_block_free(valueP->_wcs_block);
39         xmlrpc_mem_block_clean(&valueP->_block);
40         break;
41         
42     case XMLRPC_TYPE_BASE64:
43         xmlrpc_mem_block_clean(&valueP->_block);
44         break;
45
46     case XMLRPC_TYPE_ARRAY:
47         xmlrpc_destroyArrayContents(valueP);
48         break;
49         
50     case XMLRPC_TYPE_STRUCT:
51         xmlrpc_destroyStruct(valueP);
52         break;
53
54     case XMLRPC_TYPE_C_PTR:
55         break;
56
57     case XMLRPC_TYPE_NIL:
58         break;
59
60     case XMLRPC_TYPE_DEAD:
61         XMLRPC_ASSERT(false); /* Can't happen, per entry conditions */
62
63     default:
64         XMLRPC_ASSERT(false); /* There are no other possible values */
65     }
66
67     /* Next, we mark this value as invalid, to help catch refcount
68         ** errors. */
69     valueP->_type = XMLRPC_TYPE_DEAD;
70
71     /* Finally, we destroy the value itself. */
72     free(valueP);
73 }
74
75
76
77 /*=========================================================================
78 **  Reference Counting
79 **=========================================================================
80 **  Some simple reference-counting code. The xmlrpc_DECREF routine is in
81 **  charge of destroying values when their reference count equals zero.
82 */
83
84 void 
85 xmlrpc_INCREF (xmlrpc_value * const valueP) {
86
87     XMLRPC_ASSERT_VALUE_OK(valueP);
88     XMLRPC_ASSERT(valueP->_refcount > 0);
89     
90     ++valueP->_refcount;
91 }
92
93
94
95 void 
96 xmlrpc_DECREF (xmlrpc_value * const valueP) {
97
98     XMLRPC_ASSERT_VALUE_OK(valueP);
99     XMLRPC_ASSERT(valueP->_refcount > 0);
100     XMLRPC_ASSERT(valueP->_type != XMLRPC_TYPE_DEAD);
101
102     valueP->_refcount--;
103
104     /* If we have no more refs, we need to deallocate this value. */
105     if (valueP->_refcount == 0)
106         destroyValue(valueP);
107 }
108
109
110
111 /*=========================================================================
112     Utiltiies
113 =========================================================================*/
114
115 const char *
116 xmlrpc_typeName(xmlrpc_type const type) {
117
118     switch(type) {
119
120     case XMLRPC_TYPE_INT:      return "INT";
121     case XMLRPC_TYPE_BOOL:     return "BOOL";
122     case XMLRPC_TYPE_DOUBLE:   return "DOUBLE";
123     case XMLRPC_TYPE_DATETIME: return "DATETIME";
124     case XMLRPC_TYPE_STRING:   return "STRING";
125     case XMLRPC_TYPE_BASE64:   return "BASE64";
126     case XMLRPC_TYPE_ARRAY:    return "ARRAY";
127     case XMLRPC_TYPE_STRUCT:   return "STRUCT";
128     case XMLRPC_TYPE_C_PTR:    return "C_PTR";
129     case XMLRPC_TYPE_NIL:      return "NIL";
130     case XMLRPC_TYPE_DEAD:     return "DEAD";
131     default:                   return "???";
132     }
133 }
134
135
136
137 static void
138 verifyNoNulls(xmlrpc_env * const envP,
139               const char * const contents,
140               unsigned int const len) {
141 /*----------------------------------------------------------------------------
142    Verify that the character array 'contents', which is 'len' bytes long,
143    does not contain any NUL characters, which means it can be made into
144    a passable ASCIIZ string just by adding a terminating NUL.
145
146    Fail if the array contains a NUL.
147 -----------------------------------------------------------------------------*/
148     unsigned int i;
149
150     for (i = 0; i < len && !envP->fault_occurred; i++)
151         if (contents[i] == '\0')
152             xmlrpc_env_set_fault_formatted(
153                 envP, XMLRPC_TYPE_ERROR, 
154                 "String must not contain NUL characters");
155 }
156
157
158
159 #if HAVE_UNICODE_WCHAR
160
161 static void
162 verifyNoNullsW(xmlrpc_env *    const envP,
163                const wchar_t * const contents,
164                unsigned int    const len) {
165 /*----------------------------------------------------------------------------
166    Same as verifyNoNulls(), but for wide characters.
167 -----------------------------------------------------------------------------*/
168     unsigned int i;
169
170     for (i = 0; i < len && !envP->fault_occurred; i++)
171         if (contents[i] == '\0')
172             xmlrpc_env_set_fault_formatted(
173                 envP, XMLRPC_TYPE_ERROR, 
174                 "String must not contain NUL characters");
175 }
176 #endif
177
178
179
180 static void
181 validateType(xmlrpc_env *         const envP,
182              const xmlrpc_value * const valueP,
183              xmlrpc_type          const expectedType) {
184
185     if (valueP->_type != expectedType) {
186         xmlrpc_env_set_fault_formatted(
187             envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where "
188             "type %s was expected.", 
189             xmlrpc_typeName(valueP->_type), xmlrpc_typeName(expectedType));
190     }
191 }
192
193
194
195 /*=========================================================================
196     Extracting XML-RPC value
197 ===========================================================================
198   These routines extract XML-RPC values into ordinary C data types.
199
200   For array and struct values, see the separates files xmlrpc_array.c
201   and xmlrpc_struct.c.
202 =========================================================================*/
203
204 void 
205 xmlrpc_read_int(xmlrpc_env *         const envP,
206                 const xmlrpc_value * const valueP,
207                 xmlrpc_int32 *       const intValueP) {
208
209     validateType(envP, valueP, XMLRPC_TYPE_INT);
210     if (!envP->fault_occurred)
211         *intValueP = valueP->_value.i;
212 }
213
214
215
216 void
217 xmlrpc_read_bool(xmlrpc_env *         const envP,
218                  const xmlrpc_value * const valueP,
219                  xmlrpc_bool *        const boolValueP) {
220
221     validateType(envP, valueP, XMLRPC_TYPE_BOOL);
222     if (!envP->fault_occurred)
223         *boolValueP = valueP->_value.b;
224 }
225
226
227
228 void
229 xmlrpc_read_double(xmlrpc_env *         const envP,
230                    const xmlrpc_value * const valueP,
231                    xmlrpc_double *      const doubleValueP) {
232     
233     validateType(envP, valueP, XMLRPC_TYPE_DOUBLE);
234     if (!envP->fault_occurred)
235         *doubleValueP = valueP->_value.d;
236
237 }
238
239
240 /* datetime stuff is in xmlrpc_datetime.c */
241
242 static void
243 accessStringValue(xmlrpc_env *         const envP,
244                   const xmlrpc_value * const valueP,
245                   size_t *             const lengthP,
246                   const char **        const contentsP) {
247     
248     validateType(envP, valueP, XMLRPC_TYPE_STRING);
249     if (!envP->fault_occurred) {
250         unsigned int const size = 
251             XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
252         const char * const contents = 
253             XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
254         unsigned int const len = size - 1;
255             /* The memblock has a null character added to the end */
256
257         verifyNoNulls(envP, contents, len);
258
259         *lengthP = len;
260         *contentsP = contents;
261     }
262 }
263              
264
265
266 void
267 xmlrpc_read_string(xmlrpc_env *         const envP,
268                    const xmlrpc_value * const valueP,
269                    const char **        const stringValueP) {
270 /*----------------------------------------------------------------------------
271    Read the value of an XML-RPC string as an ASCIIZ string.
272
273    Return the string in newly malloc'ed storage that Caller must free.
274
275    Fail if the string contains null characters (which means it wasn't
276    really a string, but XML-RPC doesn't seem to understand what a string
277    is, and such values are possible).
278 -----------------------------------------------------------------------------*/
279     size_t length;
280     const char * contents;
281
282     accessStringValue(envP, valueP, &length, &contents);
283
284     if (!envP->fault_occurred) {
285         char * stringValue;
286             
287         stringValue = malloc(length+1);
288         if (stringValue == NULL)
289             xmlrpc_env_set_fault_formatted(
290                 envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate space "
291                 "for %u-character string", length);
292         else {
293             memcpy(stringValue, contents, length);
294             stringValue[length] = '\0';
295
296             *stringValueP = stringValue;
297         }
298     }
299 }
300
301
302
303 void
304 xmlrpc_read_string_old(xmlrpc_env *         const envP,
305                        const xmlrpc_value * const valueP,
306                        const char **        const stringValueP) {
307
308     size_t length;
309     accessStringValue(envP, valueP, &length, stringValueP);
310 }
311
312
313
314 void
315 xmlrpc_read_string_lp(xmlrpc_env *         const envP,
316                       const xmlrpc_value * const valueP,
317                       size_t *             const lengthP,
318                       const char **        const stringValueP) {
319
320     validateType(envP, valueP, XMLRPC_TYPE_STRING);
321     if (!envP->fault_occurred) {
322         unsigned int const size = 
323             XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
324         const char * const contents = 
325             XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
326
327         char * stringValue;
328
329         stringValue = malloc(size);
330         if (stringValue == NULL)
331             xmlrpc_env_set_fault_formatted(
332                 envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate %u bytes "
333                 "for string.", size);
334         else {
335             memcpy(stringValue, contents, size);
336             *stringValueP = stringValue;
337             *lengthP = size - 1;  /* Size includes terminating NUL */
338         }
339     }
340 }
341
342
343
344 void
345 xmlrpc_read_string_lp_old(xmlrpc_env *         const envP,
346                           const xmlrpc_value * const valueP,
347                           size_t *             const lengthP,
348                           const char **        const stringValueP) {
349
350     validateType(envP, valueP, XMLRPC_TYPE_STRING);
351     if (!envP->fault_occurred) {
352         *lengthP =      XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1;
353         *stringValueP = XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
354     }
355 }
356
357
358
359 static __inline__ void
360 setupWcsBlock(xmlrpc_env *   const envP,
361               xmlrpc_value * const valueP) {
362 /*----------------------------------------------------------------------------
363    Add a wcs block (wchar_t string) to the indicated xmlrpc_value if it
364    doesn't have one already.
365 -----------------------------------------------------------------------------*/
366     if (!valueP->_wcs_block) {
367         char * const contents = 
368             XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
369         size_t const len = 
370             XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1;
371         valueP->_wcs_block = 
372             xmlrpc_utf8_to_wcs(envP, contents, len + 1);
373     }
374 }
375
376
377
378 #if HAVE_UNICODE_WCHAR
379
380 static void
381 accessStringValueW(xmlrpc_env *     const envP,
382                    xmlrpc_value *   const valueP,
383                    size_t *         const lengthP,
384                    const wchar_t ** const stringValueP) {
385
386     validateType(envP, valueP, XMLRPC_TYPE_STRING);
387     if (!envP->fault_occurred) {
388         setupWcsBlock(envP, valueP);
389
390         if (!envP->fault_occurred) {
391             wchar_t * const wcontents = 
392                 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block);
393             size_t const len = 
394                 XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block) - 1;
395             
396             verifyNoNullsW(envP, wcontents, len);
397
398             *lengthP = len;
399             *stringValueP = wcontents;
400         }
401     }
402 }
403
404
405               
406 void
407 xmlrpc_read_string_w(xmlrpc_env *     const envP,
408                      xmlrpc_value *   const valueP,
409                      const wchar_t ** const stringValueP) {
410
411     size_t length;
412     const wchar_t * wcontents;
413     
414     accessStringValueW(envP, valueP, &length, &wcontents);
415
416     if (!envP->fault_occurred) {
417         wchar_t * stringValue;
418         stringValue = malloc((length + 1) * sizeof(wchar_t));
419         if (stringValue == NULL)
420             xmlrpc_env_set_fault_formatted(
421                 envP, XMLRPC_INTERNAL_ERROR, 
422                 "Unable to allocate space for %u-byte string", 
423                 length);
424         else {
425             memcpy(stringValue, wcontents, length * sizeof(wchar_t));
426             stringValue[length] = '\0';
427             
428             *stringValueP = stringValue;
429         }
430     }
431 }
432
433
434
435 void
436 xmlrpc_read_string_w_old(xmlrpc_env *     const envP,
437                          xmlrpc_value *   const valueP,
438                          const wchar_t ** const stringValueP) {
439
440     size_t length;
441
442     accessStringValueW(envP, valueP, &length, stringValueP);
443 }
444
445
446
447 void
448 xmlrpc_read_string_w_lp(xmlrpc_env *     const envP,
449                         xmlrpc_value *   const valueP,
450                         size_t *         const lengthP,
451                         const wchar_t ** const stringValueP) {
452
453     validateType(envP, valueP, XMLRPC_TYPE_STRING);
454     if (!envP->fault_occurred) {
455         setupWcsBlock(envP, valueP);
456
457         if (!envP->fault_occurred) {
458             wchar_t * const wcontents = 
459                 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block);
460             size_t const size = 
461                 XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block);
462
463             wchar_t * stringValue;
464             
465             stringValue = malloc(size * sizeof(wchar_t));
466             if (stringValue == NULL)
467                 xmlrpc_env_set_fault_formatted(
468                     envP, XMLRPC_INTERNAL_ERROR, 
469                     "Unable to allocate space for %u-byte string", 
470                     size);
471             else {
472                 memcpy(stringValue, wcontents, size * sizeof(wchar_t));
473                 
474                 *lengthP      = size - 1; /* size includes terminating NUL */
475                 *stringValueP = stringValue;
476             }
477         }
478     }
479 }
480
481
482
483 void
484 xmlrpc_read_string_w_lp_old(xmlrpc_env *     const envP,
485                             xmlrpc_value *   const valueP,
486                             size_t *         const lengthP,
487                             const wchar_t ** const stringValueP) {
488
489     validateType(envP, valueP, XMLRPC_TYPE_STRING);
490     if (!envP->fault_occurred) {
491         setupWcsBlock(envP, valueP);
492
493         if (!envP->fault_occurred) {
494             wchar_t * const wcontents = 
495                 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block);
496             size_t const size = 
497                 XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block);
498             
499             *lengthP      = size - 1;  /* size includes terminatnig NUL */
500             *stringValueP = wcontents;
501         }
502     }
503 }
504 #endif
505
506
507
508 void
509 xmlrpc_read_base64(xmlrpc_env *           const envP,
510                    const xmlrpc_value *   const valueP,
511                    size_t *               const lengthP,
512                    const unsigned char ** const byteStringValueP) {
513
514     validateType(envP, valueP, XMLRPC_TYPE_BASE64);
515     if (!envP->fault_occurred) {
516         size_t const size = 
517             XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
518         const char * const contents = 
519             XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
520
521         char * byteStringValue;
522
523         byteStringValue = malloc(size);
524         if (byteStringValue == NULL)
525             xmlrpc_env_set_fault_formatted(
526                 envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate %u bytes "
527                 "for byte string.", size);
528         else {
529             memcpy(byteStringValue, contents, size);
530             *byteStringValueP = (const unsigned char *)byteStringValue;
531             *lengthP = size;
532         }
533     }
534 }
535
536
537
538 void
539 xmlrpc_read_base64_old(xmlrpc_env *           const envP,
540                        const xmlrpc_value *   const valueP,
541                        size_t *               const lengthP,
542                        const unsigned char ** const byteStringValueP) {
543
544     validateType(envP, valueP, XMLRPC_TYPE_BASE64);
545     if (!envP->fault_occurred) {
546         *lengthP =
547             XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
548         *byteStringValueP = (const unsigned char *)
549             XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
550     }
551 }
552
553
554
555 void
556 xmlrpc_read_base64_size(xmlrpc_env *           const envP,
557                         const xmlrpc_value *   const valueP,
558                         size_t *               const lengthP) {
559
560     validateType(envP, valueP, XMLRPC_TYPE_BASE64);
561     if (!envP->fault_occurred)
562         *lengthP = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
563 }
564
565
566
567 void
568 xmlrpc_read_nil(xmlrpc_env *   const envP,
569                 xmlrpc_value * const valueP) {
570 /*----------------------------------------------------------------------------
571    Read out the value of a nil value.  It doesn't have one, of course, so
572    this is essentially a no-op.  But it does validate the type and is
573    necessary to match all the other types.
574 -----------------------------------------------------------------------------*/
575     validateType(envP, valueP, XMLRPC_TYPE_NIL);
576 }
577
578
579
580 void
581 xmlrpc_read_cptr(xmlrpc_env *         const envP,
582                  const xmlrpc_value * const valueP,
583                  void **              const ptrValueP) {
584
585     validateType(envP, valueP, XMLRPC_TYPE_C_PTR);
586     if (!envP->fault_occurred)
587         *ptrValueP = valueP->_value.c_ptr;
588 }
589
590
591
592 xmlrpc_type xmlrpc_value_type (xmlrpc_value* value)
593 {
594     XMLRPC_ASSERT_VALUE_OK(value);
595     return value->_type;
596 }
597
598
599
600 void
601 xmlrpc_createXmlrpcValue(xmlrpc_env *    const envP,
602                          xmlrpc_value ** const valPP) {
603 /*----------------------------------------------------------------------------
604    Create a blank xmlrpc_value to be filled in.
605
606    Set the reference count to 1.
607 -----------------------------------------------------------------------------*/
608     xmlrpc_value * valP;
609
610     MALLOCVAR(valP);
611     if (!valP)
612         xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
613                              "Could not allocate memory for xmlrpc_value");
614     else
615         valP->_refcount = 1;
616
617     *valPP = valP;
618 }
619
620
621
622 xmlrpc_value *
623 xmlrpc_int_new(xmlrpc_env * const envP, 
624                xmlrpc_int32 const value) {
625
626     xmlrpc_value * valP;
627
628     xmlrpc_createXmlrpcValue(envP, &valP);
629
630     if (!envP->fault_occurred) {
631         valP->_type    = XMLRPC_TYPE_INT;
632         valP->_value.i = value;
633     }
634     return valP;
635 }
636
637
638
639 xmlrpc_value *
640 xmlrpc_bool_new(xmlrpc_env * const envP, 
641                 xmlrpc_bool  const value) {
642
643     xmlrpc_value * valP;
644
645     xmlrpc_createXmlrpcValue(envP, &valP);
646
647     if (!envP->fault_occurred) {
648         valP->_type = XMLRPC_TYPE_BOOL;
649         valP->_value.b = value;
650     }
651     return valP;
652 }
653
654
655
656 xmlrpc_value *
657 xmlrpc_double_new(xmlrpc_env * const envP, 
658                   double       const value) {
659
660     xmlrpc_value * valP;
661
662     xmlrpc_createXmlrpcValue(envP, &valP);
663
664     if (!envP->fault_occurred) {
665         valP->_type = XMLRPC_TYPE_DOUBLE;
666         valP->_value.d = value;
667     }
668     return valP;
669 }
670
671
672
673 xmlrpc_value *
674 xmlrpc_string_new_lp(xmlrpc_env * const envP, 
675                      size_t       const length,
676                      const char * const value) {
677
678     xmlrpc_value * valP;
679
680     xmlrpc_createXmlrpcValue(envP, &valP);
681
682     if (!envP->fault_occurred) {
683         valP->_type = XMLRPC_TYPE_STRING;
684         valP->_wcs_block = NULL;
685         XMLRPC_MEMBLOCK_INIT(char, envP, &valP->_block, length + 1);
686         if (!envP->fault_occurred) {
687             char * const contents =
688                 XMLRPC_MEMBLOCK_CONTENTS(char, &valP->_block);
689             memcpy(contents, value, length);
690             contents[length] = '\0';
691         }
692         if (envP->fault_occurred)
693             free(valP);
694     }
695     return valP;
696 }
697
698
699
700 xmlrpc_value *
701 xmlrpc_string_new(xmlrpc_env * const envP,
702                   const char * const value) {
703
704     return xmlrpc_string_new_lp(envP, strlen(value), value);
705 }
706
707
708 #if HAVE_UNICODE_WCHAR
709 xmlrpc_value *
710 xmlrpc_string_w_new_lp(xmlrpc_env *    const envP, 
711                        size_t          const length,
712                        const wchar_t * const value) {
713
714     xmlrpc_value * valP;
715
716     /* Initialize our XML-RPC value. */
717     xmlrpc_createXmlrpcValue(envP, &valP);
718
719     if (!envP->fault_occurred) {
720         valP->_type = XMLRPC_TYPE_STRING;
721
722         /* Build our wchar_t block first. */
723         valP->_wcs_block =
724             XMLRPC_MEMBLOCK_NEW(wchar_t, envP, length + 1);
725         if (!envP->fault_occurred) {
726             wchar_t * const wcs_contents =
727                 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valP->_wcs_block);
728
729             xmlrpc_mem_block * utf8P;
730
731             memcpy(wcs_contents, value, length * sizeof(wchar_t));
732             wcs_contents[length] = '\0';
733     
734             /* Convert the wcs block to UTF-8. */
735             utf8P = xmlrpc_wcs_to_utf8(envP, wcs_contents, length + 1);
736             if (!envP->fault_occurred) {
737                 char * const utf8_contents =
738                     XMLRPC_MEMBLOCK_CONTENTS(char, utf8P);
739                 size_t const utf8_len = XMLRPC_MEMBLOCK_SIZE(char, utf8P);
740
741                 /* XXX - We need an extra memcopy to initialize _block. */
742                 XMLRPC_MEMBLOCK_INIT(char, envP, &valP->_block, utf8_len);
743                 if (!envP->fault_occurred) {
744                     char * contents;
745                     contents = XMLRPC_MEMBLOCK_CONTENTS(char, &valP->_block);
746                     memcpy(contents, utf8_contents, utf8_len);
747                 }
748                 XMLRPC_MEMBLOCK_FREE(char, utf8P);
749             }
750             if (envP->fault_occurred)
751                 XMLRPC_MEMBLOCK_FREE(wchar_t, valP->_wcs_block);
752         }
753         if (envP->fault_occurred)
754             free(valP);
755     }
756     return valP;
757 }
758
759
760
761 xmlrpc_value *
762 xmlrpc_string_w_new(xmlrpc_env *    const envP,
763                     const wchar_t * const value) {
764     return xmlrpc_string_w_new_lp(envP, wcslen(value), value);
765 }
766 #endif
767
768 xmlrpc_value *
769 xmlrpc_base64_new(xmlrpc_env *          const envP, 
770                   size_t                const length,
771                   const unsigned char * const value) {
772
773     xmlrpc_value * valP;
774
775     xmlrpc_createXmlrpcValue(envP, &valP);
776
777     if (!envP->fault_occurred) {
778         valP->_type = XMLRPC_TYPE_BASE64;
779
780         xmlrpc_mem_block_init(envP, &valP->_block, length);
781         if (!envP->fault_occurred) {
782             char * const contents = 
783                 xmlrpc_mem_block_contents(&valP->_block);
784             memcpy(contents, value, length);
785         }
786         if (envP->fault_occurred)
787             free(valP);
788     }
789     return valP;
790 }
791
792
793
794 /* array stuff is in xmlrpc_array.c */
795
796
797
798 xmlrpc_value *
799 xmlrpc_cptr_new(xmlrpc_env *    const envP,
800                 void *          const value) {
801
802     xmlrpc_value * valP;
803
804     xmlrpc_createXmlrpcValue(envP, &valP);
805
806     if (!envP->fault_occurred) {
807         valP->_type = XMLRPC_TYPE_C_PTR;
808         valP->_value.c_ptr = value;
809     }
810     return valP;
811 }
812
813
814
815 xmlrpc_value *
816 xmlrpc_nil_new(xmlrpc_env *    const envP) {
817     xmlrpc_value * valP;
818
819     xmlrpc_createXmlrpcValue(envP, &valP);
820     if (!envP->fault_occurred)
821         valP->_type = XMLRPC_TYPE_NIL;
822
823     return valP;
824 }
825
826
827
828 /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
829 ** Copyright (C) 2001 by Eric Kidd. All rights reserved.
830 **
831 ** Redistribution and use in source and binary forms, with or without
832 ** modification, are permitted provided that the following conditions
833 ** are met:
834 ** 1. Redistributions of source code must retain the above copyright
835 **    notice, this list of conditions and the following disclaimer.
836 ** 2. Redistributions in binary form must reproduce the above copyright
837 **    notice, this list of conditions and the following disclaimer in the
838 **    documentation and/or other materials provided with the distribution.
839 ** 3. The name of the author may not be used to endorse or promote products
840 **    derived from this software without specific prior written permission. 
841 **  
842 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
843 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
844 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
845 ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
846 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
847 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
848 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
849 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
850 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
851 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
852 ** SUCH DAMAGE. */