2 * Copyright (c) 1999-2009 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
28 #include <mach/mach.h>
29 #include <servers/bootstrap.h>
40 #define ILS_MAGIC_SIZE 8
41 #define ILS_MAGIC "ILSMAGIC"
45 static const uint32_t align_32
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 4 };
46 static const uint32_t align_64
[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
49 padsize(size_t curr
, size_t item
, const uint32_t *align
)
53 if (item
> 8) item
= 8;
56 if (na
== 0) return 0;
59 if (diff
== 0) return 0;
65 * Create a structure using in-line memory (i.e. all one blob).
66 * This reduces malloc/free workload.
68 * Structure components may be strings, 1, 2, 4, or 8-byte values,
69 * lists of strings, or lists of 4, 8, or 16-byte values.
72 * s NUL terminated string
77 * S 128 byte value (_SS_MAXSIZE for a sockaddr)
78 * L long (32 or 64 bits, depending on architecture)
80 * * NULL-terminated list of strings
81 * a NULL-terminated list of 4-byte values
82 * b NULL-terminated list of 8-byte values
83 * c NULL-terminated list of 16-byte values
84 * @ length (4 bytes) and buffer (requires two parameters)
88 LI_ils_create(char *fmt
, ...)
93 void *hp
, *dp
, *lp
, *ils
;
101 size_t memsize
, hsize
, csize
, csizep1
, csizep2
, slen
, largest
;
102 const uint32_t *align
;
104 if (fmt
== NULL
) return NULL
;
108 if (sizeof(char *) == 8) align
= align_64
;
110 /* first pass: calculate size */
111 memsize
= ILS_MAGIC_SIZE
;
116 for (f
= fmt
; (*f
) != '\0'; f
++)
125 if (largest
< sizeof(char *)) largest
= sizeof(char *);
127 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
128 arg
= va_arg(ap
, char *);
129 if (arg
!= NULL
) slen
= strlen(arg
) + 1;
136 if (largest
< 1) largest
= 1;
139 u8
= va_arg(ap
, int);
146 if (largest
< 2) largest
= 2;
148 csize
= 2 + padsize(hsize
, 2, align
);
149 u16
= va_arg(ap
, int);
156 if (largest
< 4) largest
= 4;
158 csize
= 4 + padsize(hsize
, 4, align
);
159 u32
= va_arg(ap
, uint32_t);
166 if (largest
< 8) largest
= 8;
168 csize
= 8 + padsize(hsize
, 8, align
);
169 u64
= va_arg(ap
, uint64_t);
176 if (largest
< 128) largest
= 128;
178 /* 4-byte-align since a socket_data_t is really just a buffer */
179 csize
= 128 + padsize(hsize
, 4, align
);
180 sdata
= va_arg(ap
, socket_data_t
);
187 if (largest
< sizeof(unsigned long)) largest
= sizeof(unsigned long);
189 csize
= sizeof(unsigned long) + padsize(hsize
, sizeof(unsigned long), align
);
190 l
= va_arg(ap
, unsigned long);
197 if (largest
< sizeof(mach_port_t
)) largest
= sizeof(mach_port_t
);
199 csize
= sizeof(mach_port_t
) + padsize(hsize
, sizeof(mach_port_t
), align
);
200 m
= va_arg(ap
, mach_port_t
);
207 /* NULL-terminated list of strings */
208 if (largest
< sizeof(char *)) largest
= sizeof(char *);
210 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
211 list
= va_arg(ap
, char **);
214 for (i
= 0; list
[i
] != NULL
; i
++)
216 slen
+= sizeof(char *);
217 slen
+= (strlen(list
[i
]) + 1);
220 slen
+= sizeof(char *);
228 /* NULL-terminated list of 4-byte values */
229 if (largest
< sizeof(char *)) largest
= sizeof(char *);
231 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
232 list
= va_arg(ap
, char **);
235 for (i
= 0; list
[i
] != NULL
; i
++)
237 slen
+= sizeof(char *);
241 slen
+= sizeof(char *);
249 /* NULL-terminated list of 8-byte values */
250 if (largest
< sizeof(char *)) largest
= sizeof(char *);
252 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
253 list
= va_arg(ap
, char **);
256 for (i
= 0; list
[i
] != NULL
; i
++)
258 slen
+= sizeof(char *);
262 slen
+= sizeof(char *);
270 /* NULL-terminated list of 16-byte values */
271 if (largest
< sizeof(char *)) largest
= sizeof(char *);
273 csize
= sizeof(char *) + padsize(hsize
, sizeof(char *), align
);
274 list
= va_arg(ap
, char **);
277 for (i
= 0; list
[i
] != NULL
; i
++)
279 slen
+= sizeof(char *);
283 slen
+= sizeof(char *);
291 if (largest
< 4) largest
= 4;
292 csizep1
= 4 + padsize(hsize
, 4, align
);
293 slen
= va_arg(ap
, uint32_t);
295 if (largest
< sizeof(char *)) largest
= sizeof(char *);
296 csizep2
= sizeof(char *) + padsize(hsize
+ csizep1
, sizeof(char *), align
);
297 arg
= va_arg(ap
, char *);
299 csize
= csizep1
+ csizep2
;
304 default: return NULL
;
314 pad
= padsize(hsize
, largest
, align
);
318 ils
= malloc(memsize
);
325 /* insert magic cookie */
327 memcpy(dp
, ILS_MAGIC
, ILS_MAGIC_SIZE
);
328 dp
+= ILS_MAGIC_SIZE
;
333 /* second pass: copy data */
335 for (f
= fmt
; (*f
) != '\0'; f
++)
341 pad
= padsize(hsize
, sizeof(char *), align
);
349 arg
= va_arg(ap
, char *);
352 memset(hp
, 0, sizeof(char *));
356 memcpy(hp
, &dp
, sizeof(char *));
357 slen
= strlen(arg
) + 1;
358 memcpy(dp
, arg
, slen
);
362 hp
+= sizeof(char *);
363 hsize
+= sizeof(char *);
370 u8
= va_arg(ap
, int);
371 memcpy(hp
, &u8
, sizeof(uint8_t));
372 hp
+= sizeof(uint8_t);
379 pad
= padsize(hsize
, 2, align
);
387 u16
= va_arg(ap
, int);
388 memcpy(hp
, &u16
, sizeof(uint16_t));
390 hp
+= sizeof(uint16_t);
391 hsize
+= sizeof(uint16_t);
398 pad
= padsize(hsize
, 4, align
);
406 u32
= va_arg(ap
, uint32_t);
407 memcpy(hp
, &u32
, sizeof(uint32_t));
409 hp
+= sizeof(uint32_t);
410 hsize
+= sizeof(uint32_t);
417 pad
= padsize(hsize
, 8, align
);
425 u64
= va_arg(ap
, uint64_t);
426 memcpy(hp
, &u64
, sizeof(uint64_t));
428 hp
+= sizeof(uint64_t);
429 hsize
+= sizeof(uint64_t);
436 pad
= padsize(hsize
, 4, align
);
444 sdata
= va_arg(ap
, socket_data_t
);
445 memcpy(hp
, (char *)(sdata
.x
), sizeof(socket_data_t
));
447 hp
+= sizeof(socket_data_t
);
448 hsize
+= sizeof(socket_data_t
);
455 pad
= padsize(hsize
, sizeof(unsigned long), align
);
463 l
= va_arg(ap
, unsigned long);
464 memcpy(hp
, &l
, sizeof(unsigned long));
466 hp
+= sizeof(unsigned long);
467 hsize
+= sizeof(unsigned long);
474 pad
= padsize(hsize
, sizeof(mach_port_t
), align
);
482 m
= va_arg(ap
, mach_port_t
);
483 memcpy(hp
, &m
, sizeof(mach_port_t
));
485 hp
+= sizeof(mach_port_t
);
486 hsize
+= sizeof(mach_port_t
);
493 pad
= padsize(hsize
, sizeof(char *), align
);
501 list
= va_arg(ap
, char **);
505 memset(hp
, 0, sizeof(char *));
509 memcpy(hp
, &dp
, sizeof(char *));
511 for (i
= 0; list
[i
] != NULL
; i
++);
514 dp
+= ((i
+ 1) * sizeof(char *));
516 for (i
= 0; list
[i
] != NULL
; i
++)
518 memcpy(lp
, &dp
, sizeof(char *));
519 lp
+= sizeof(char *);
520 slen
= strlen(list
[i
]) + 1;
521 memcpy(dp
, list
[i
], slen
);
525 memset(lp
, 0, sizeof(char *));
528 hp
+= sizeof(char *);
529 hsize
+= sizeof(char *);
536 pad
= padsize(hsize
, sizeof(char *), align
);
544 list
= va_arg(ap
, char **);
548 memset(hp
, 0, sizeof(char *));
552 memcpy(hp
, &dp
, sizeof(char *));
554 for (i
= 0; list
[i
] != NULL
; i
++);
557 dp
+= ((i
+ 1) * sizeof(char *));
559 for (i
= 0; list
[i
] != NULL
; i
++)
561 memcpy(lp
, &dp
, sizeof(char *));
562 lp
+= sizeof(char *);
564 memcpy(dp
, list
[i
], slen
);
568 memset(lp
, 0, sizeof(char *));
571 hp
+= sizeof(char *);
572 hsize
+= sizeof(char *);
579 pad
= padsize(hsize
, sizeof(char *), align
);
587 list
= va_arg(ap
, char **);
591 memset(hp
, 0, sizeof(char *));
595 memcpy(hp
, &dp
, sizeof(char *));
597 for (i
= 0; list
[i
] != NULL
; i
++);
600 dp
+= ((i
+ 1) * sizeof(char *));
602 for (i
= 0; list
[i
] != NULL
; i
++)
604 memcpy(lp
, &dp
, sizeof(char *));
605 lp
+= sizeof(char *);
607 memcpy(dp
, list
[i
], slen
);
611 memset(lp
, 0, sizeof(char *));
614 hp
+= sizeof(char *);
615 hsize
+= sizeof(char *);
622 pad
= padsize(hsize
, sizeof(char *), align
);
630 list
= va_arg(ap
, char **);
634 memset(hp
, 0, sizeof(char *));
638 memcpy(hp
, &dp
, sizeof(char *));
640 for (i
= 0; list
[i
] != NULL
; i
++);
643 dp
+= ((i
+ 1) * sizeof(char *));
645 for (i
= 0; list
[i
] != NULL
; i
++)
647 memcpy(lp
, &dp
, sizeof(char *));
648 lp
+= sizeof(char *);
650 memcpy(dp
, list
[i
], slen
);
654 memset(lp
, 0, sizeof(char *));
657 hp
+= sizeof(char *);
658 hsize
+= sizeof(char *);
665 pad
= padsize(hsize
, 4, align
);
673 slen
= va_arg(ap
, uint32_t);
674 memcpy(hp
, &slen
, sizeof(uint32_t));
676 hp
+= sizeof(uint32_t);
677 hsize
+= sizeof(uint32_t);
679 pad
= padsize(hsize
, sizeof(char *), align
);
687 arg
= va_arg(ap
, char *);
690 memset(hp
, 0, sizeof(char *));
694 memcpy(hp
, &dp
, sizeof(char *));
695 memcpy(dp
, arg
, slen
);
699 hp
+= sizeof(char *);
700 hsize
+= sizeof(char *);
707 pad
= padsize(hsize
, largest
, align
);
708 if (pad
> 0) memset(hp
, 0, pad
);