3 * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 * 2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
12 * He still hopefully carried some of his gear in his pack: a small tinder-box,
13 * two small shallow pans, the smaller fitting into the larger; inside them a
14 * wooden spoon, a short two-pronged fork and some skewers were stowed; and
15 * hidden at the bottom of the pack in a flat wooden box a dwindling treasure,
19 /* This file contains pp ("push/pop") functions that
20 * execute the opcodes that make up a perl program. A typical pp function
21 * expects to find its arguments on the stack, and usually pushes its
22 * results onto the stack, hence the 'pp' terminology. Each OP structure
23 * contains a pointer to the relevant pp_foo() function.
25 * This particular file just contains pp_pack() and pp_unpack(). See the
26 * other pp*.c files for the rest of the pp_ functions.
31 #define PERL_IN_PP_PACK_C
35 * Offset for integer pack/unpack.
37 * On architectures where I16 and I32 aren't really 16 and 32 bits,
38 * which for now are all Crays, pack and unpack have to play games.
42 * These values are required for portability of pack() output.
43 * If they're not right on your machine, then pack() and unpack()
44 * wouldn't work right anyway; you'll need to apply the Cray hack.
45 * (I'd like to check them with #if, but you can't use sizeof() in
46 * the preprocessor.) --???
49 The appropriate SHORTSIZE, INTSIZE, LONGSIZE, and LONGLONGSIZE
50 defines are now in config.h. --Andy Dougherty April 1998
55 /* CROSSCOMPILE and MULTIARCH are going to affect pp_pack() and pp_unpack().
58 #if U16SIZE > SIZE16 || U32SIZE > SIZE32
59 # if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 /* little-endian */
60 # define OFF16(p) (char*)(p)
61 # define OFF32(p) (char*)(p)
63 # if BYTEORDER == 0x4321 || BYTEORDER == 0x87654321 /* big-endian */
64 # define OFF16(p) ((char*)(p) + (sizeof(U16) - SIZE16))
65 # define OFF32(p) ((char*)(p) + (sizeof(U32) - SIZE32))
67 }}}} bad cray byte order
70 # define COPY16(s,p) (*(p) = 0, Copy(s, OFF16(p), SIZE16, char))
71 # define COPY32(s,p) (*(p) = 0, Copy(s, OFF32(p), SIZE32, char))
72 # define COPYNN(s,p,n) (*(p) = 0, Copy(s, (char *)(p), n, char))
73 # define CAT16(sv,p) sv_catpvn(sv, OFF16(p), SIZE16)
74 # define CAT32(sv,p) sv_catpvn(sv, OFF32(p), SIZE32)
76 # define COPY16(s,p) Copy(s, p, SIZE16, char)
77 # define COPY32(s,p) Copy(s, p, SIZE32, char)
78 # define COPYNN(s,p,n) Copy(s, (char *)(p), n, char)
79 # define CAT16(sv,p) sv_catpvn(sv, (char*)(p), SIZE16)
80 # define CAT32(sv,p) sv_catpvn(sv, (char*)(p), SIZE32)
83 /* Avoid stack overflow due to pathological templates. 100 should be plenty. */
84 #define MAX_SUB_TEMPLATE_LEVEL 100
86 /* flags (note that type modifiers can also be used as flags!) */
87 #define FLAG_UNPACK_ONLY_ONE 0x10
88 #define FLAG_UNPACK_DO_UTF8 0x08
89 #define FLAG_SLASH 0x04
90 #define FLAG_COMMA 0x02
91 #define FLAG_PACK 0x01
94 S_mul128(pTHX_ SV *sv, U8 m)
97 char *s = SvPV(sv, len);
101 if (!strnEQ(s, "0000", 4)) { /* need to grow sv */
102 SV *tmpNew = newSVpvn("0000000000", 10);
104 sv_catsv(tmpNew, sv);
105 SvREFCNT_dec(sv); /* free old sv */
110 while (!*t) /* trailing '\0'? */
113 i = ((*t - '0') << 7) + m;
114 *(t--) = '0' + (char)(i % 10);
120 /* Explosives and implosives. */
122 #if 'I' == 73 && 'J' == 74
123 /* On an ASCII/ISO kind of system */
124 #define ISUUCHAR(ch) ((ch) >= ' ' && (ch) < 'a')
127 Some other sort of character set - use memchr() so we don't match
130 #define ISUUCHAR(ch) (memchr(PL_uuemap, (ch), sizeof(PL_uuemap)-1) || (ch) == ' ')
134 #define TYPE_IS_SHRIEKING 0x100
135 #define TYPE_IS_BIG_ENDIAN 0x200
136 #define TYPE_IS_LITTLE_ENDIAN 0x400
137 #define TYPE_ENDIANNESS_MASK (TYPE_IS_BIG_ENDIAN|TYPE_IS_LITTLE_ENDIAN)
138 #define TYPE_ENDIANNESS(t) ((t) & TYPE_ENDIANNESS_MASK)
139 #define TYPE_NO_ENDIANNESS(t) ((t) & ~TYPE_ENDIANNESS_MASK)
140 #define TYPE_MODIFIERS(t) ((t) & ~0xFF)
141 #define TYPE_NO_MODIFIERS(t) ((t) & 0xFF)
143 #define ENDIANNESS_ALLOWED_TYPES "sSiIlLqQjJfFdDpP("
145 #define DO_BO_UNPACK(var, type) \
147 switch (TYPE_ENDIANNESS(datumtype)) { \
148 case TYPE_IS_BIG_ENDIAN: var = my_betoh ## type (var); break; \
149 case TYPE_IS_LITTLE_ENDIAN: var = my_letoh ## type (var); break; \
154 #define DO_BO_PACK(var, type) \
156 switch (TYPE_ENDIANNESS(datumtype)) { \
157 case TYPE_IS_BIG_ENDIAN: var = my_htobe ## type (var); break; \
158 case TYPE_IS_LITTLE_ENDIAN: var = my_htole ## type (var); break; \
163 #define DO_BO_UNPACK_PTR(var, type, pre_cast) \
165 switch (TYPE_ENDIANNESS(datumtype)) { \
166 case TYPE_IS_BIG_ENDIAN: \
167 var = (void *) my_betoh ## type ((pre_cast) var); \
169 case TYPE_IS_LITTLE_ENDIAN: \
170 var = (void *) my_letoh ## type ((pre_cast) var); \
177 #define DO_BO_PACK_PTR(var, type, pre_cast) \
179 switch (TYPE_ENDIANNESS(datumtype)) { \
180 case TYPE_IS_BIG_ENDIAN: \
181 var = (void *) my_htobe ## type ((pre_cast) var); \
183 case TYPE_IS_LITTLE_ENDIAN: \
184 var = (void *) my_htole ## type ((pre_cast) var); \
191 #define BO_CANT_DOIT(action, type) \
193 switch (TYPE_ENDIANNESS(datumtype)) { \
194 case TYPE_IS_BIG_ENDIAN: \
195 Perl_croak(aTHX_ "Can't %s big-endian %ss on this " \
196 "platform", #action, #type); \
198 case TYPE_IS_LITTLE_ENDIAN: \
199 Perl_croak(aTHX_ "Can't %s little-endian %ss on this " \
200 "platform", #action, #type); \
207 #if PTRSIZE == INTSIZE
208 # define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, i, int)
209 # define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, i, int)
210 #elif PTRSIZE == LONGSIZE
211 # define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, l, long)
212 # define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, l, long)
214 # define DO_BO_UNPACK_P(var) BO_CANT_DOIT(unpack, pointer)
215 # define DO_BO_PACK_P(var) BO_CANT_DOIT(pack, pointer)
218 #if defined(my_htolen) && defined(my_letohn) && \
219 defined(my_htoben) && defined(my_betohn)
220 # define DO_BO_UNPACK_N(var, type) \
222 switch (TYPE_ENDIANNESS(datumtype)) { \
223 case TYPE_IS_BIG_ENDIAN: my_betohn(&var, sizeof(type)); break;\
224 case TYPE_IS_LITTLE_ENDIAN: my_letohn(&var, sizeof(type)); break;\
229 # define DO_BO_PACK_N(var, type) \
231 switch (TYPE_ENDIANNESS(datumtype)) { \
232 case TYPE_IS_BIG_ENDIAN: my_htoben(&var, sizeof(type)); break;\
233 case TYPE_IS_LITTLE_ENDIAN: my_htolen(&var, sizeof(type)); break;\
238 # define DO_BO_UNPACK_N(var, type) BO_CANT_DOIT(unpack, type)
239 # define DO_BO_PACK_N(var, type) BO_CANT_DOIT(pack, type)
242 /* Returns the sizeof() struct described by pat */
244 S_measure_struct(pTHX_ register tempsym_t* symptr)
246 register I32 len = 0;
247 register I32 total = 0;
252 while (next_symbol(symptr)) {
254 switch( symptr->howlen ){
257 len = symptr->length;
260 Perl_croak(aTHX_ "Within []-length '*' not allowed in %s",
261 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
265 /* endianness doesn't influence the size of a type */
266 switch(TYPE_NO_ENDIANNESS(symptr->code)) {
268 Perl_croak(aTHX_ "Invalid type '%c' in %s",
269 (int)TYPE_NO_MODIFIERS(symptr->code),
270 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
273 case 'U': /* XXXX Is it correct? */
276 Perl_croak(aTHX_ "Within []-length '%c' not allowed in %s",
278 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
284 tempsym_t savsym = *symptr;
285 symptr->patptr = savsym.grpbeg;
286 symptr->patend = savsym.grpend;
287 /* XXXX Theoretically, we need to measure many times at different
288 positions, since the subexpression may contain
289 alignment commands, but be not of aligned length.
290 Need to detect this and croak(). */
291 size = measure_struct(symptr);
295 case 'X' | TYPE_IS_SHRIEKING:
296 /* XXXX Is this useful? Then need to treat MEASURE_BACKWARDS. */
297 if (!len) /* Avoid division by 0 */
299 len = total % len; /* Assumed: the start is aligned. */
304 Perl_croak(aTHX_ "'X' outside of string in %s",
305 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
307 case 'x' | TYPE_IS_SHRIEKING:
308 if (!len) /* Avoid division by 0 */
310 star = total % len; /* Assumed: the start is aligned. */
311 if (star) /* Other portable ways? */
334 case 's' | TYPE_IS_SHRIEKING:
335 #if SHORTSIZE != SIZE16
336 size = sizeof(short);
344 case 'S' | TYPE_IS_SHRIEKING:
345 #if SHORTSIZE != SIZE16
346 size = sizeof(unsigned short);
351 case 'v' | TYPE_IS_SHRIEKING:
352 case 'n' | TYPE_IS_SHRIEKING:
358 case 'i' | TYPE_IS_SHRIEKING:
362 case 'I' | TYPE_IS_SHRIEKING:
364 size = sizeof(unsigned int);
372 case 'l' | TYPE_IS_SHRIEKING:
373 #if LONGSIZE != SIZE32
382 case 'L' | TYPE_IS_SHRIEKING:
383 #if LONGSIZE != SIZE32
384 size = sizeof(unsigned long);
389 case 'V' | TYPE_IS_SHRIEKING:
390 case 'N' | TYPE_IS_SHRIEKING:
400 size = sizeof(char*);
404 size = sizeof(Quad_t);
407 size = sizeof(Uquad_t);
411 size = sizeof(float);
414 size = sizeof(double);
419 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
421 size = LONG_DOUBLESIZE;
431 /* locate matching closing parenthesis or bracket
432 * returns char pointer to char after match, or NULL
435 S_group_end(pTHX_ register char *patptr, register char *patend, char ender)
437 while (patptr < patend) {
445 while (patptr < patend && *patptr != '\n')
449 patptr = group_end(patptr, patend, ')') + 1;
451 patptr = group_end(patptr, patend, ']') + 1;
453 Perl_croak(aTHX_ "No group ending character '%c' found in template",
459 /* Convert unsigned decimal number to binary.
460 * Expects a pointer to the first digit and address of length variable
461 * Advances char pointer to 1st non-digit char and returns number
464 S_get_num(pTHX_ register char *patptr, I32 *lenptr )
466 I32 len = *patptr++ - '0';
467 while (isDIGIT(*patptr)) {
468 if (len >= 0x7FFFFFFF/10)
469 Perl_croak(aTHX_ "pack/unpack repeat count overflow");
470 len = (len * 10) + (*patptr++ - '0');
476 /* The marvellous template parsing routine: Using state stored in *symptr,
477 * locates next template code and count
480 S_next_symbol(pTHX_ register tempsym_t* symptr )
482 register char* patptr = symptr->patptr;
483 register char* patend = symptr->patend;
485 symptr->flags &= ~FLAG_SLASH;
487 while (patptr < patend) {
488 if (isSPACE(*patptr))
490 else if (*patptr == '#') {
492 while (patptr < patend && *patptr != '\n')
497 /* We should have found a template code */
498 I32 code = *patptr++ & 0xFF;
499 U32 inherited_modifiers = 0;
501 if (code == ','){ /* grandfather in commas but with a warning */
502 if (((symptr->flags & FLAG_COMMA) == 0) && ckWARN(WARN_UNPACK)){
503 symptr->flags |= FLAG_COMMA;
504 Perl_warner(aTHX_ packWARN(WARN_UNPACK),
505 "Invalid type ',' in %s",
506 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
511 /* for '(', skip to ')' */
513 if( isDIGIT(*patptr) || *patptr == '*' || *patptr == '[' )
514 Perl_croak(aTHX_ "()-group starts with a count in %s",
515 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
516 symptr->grpbeg = patptr;
517 patptr = 1 + ( symptr->grpend = group_end(patptr, patend, ')') );
518 if( symptr->level >= MAX_SUB_TEMPLATE_LEVEL )
519 Perl_croak(aTHX_ "Too deeply nested ()-groups in %s",
520 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
523 /* look for group modifiers to inherit */
524 if (TYPE_ENDIANNESS(symptr->flags)) {
525 if (strchr(ENDIANNESS_ALLOWED_TYPES, TYPE_NO_MODIFIERS(code)))
526 inherited_modifiers |= TYPE_ENDIANNESS(symptr->flags);
529 /* look for modifiers */
530 while (patptr < patend) {
535 modifier = TYPE_IS_SHRIEKING;
536 allowed = "sSiIlLxXnNvV";
539 modifier = TYPE_IS_BIG_ENDIAN;
540 allowed = ENDIANNESS_ALLOWED_TYPES;
543 modifier = TYPE_IS_LITTLE_ENDIAN;
544 allowed = ENDIANNESS_ALLOWED_TYPES;
553 if (!strchr(allowed, TYPE_NO_MODIFIERS(code)))
554 Perl_croak(aTHX_ "'%c' allowed only after types %s in %s", *patptr,
555 allowed, symptr->flags & FLAG_PACK ? "pack" : "unpack" );
557 if (TYPE_ENDIANNESS(code | modifier) == TYPE_ENDIANNESS_MASK)
558 Perl_croak(aTHX_ "Can't use both '<' and '>' after type '%c' in %s",
559 (int) TYPE_NO_MODIFIERS(code),
560 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
561 else if (TYPE_ENDIANNESS(code | modifier | inherited_modifiers) ==
562 TYPE_ENDIANNESS_MASK)
563 Perl_croak(aTHX_ "Can't use '%c' in a group with different byte-order in %s",
564 *patptr, symptr->flags & FLAG_PACK ? "pack" : "unpack" );
566 if (ckWARN(WARN_UNPACK)) {
568 Perl_warner(aTHX_ packWARN(WARN_UNPACK),
569 "Duplicate modifier '%c' after '%c' in %s",
570 *patptr, (int) TYPE_NO_MODIFIERS(code),
571 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
578 /* inherit modifiers */
579 code |= inherited_modifiers;
581 /* look for count and/or / */
582 if (patptr < patend) {
583 if (isDIGIT(*patptr)) {
584 patptr = get_num( patptr, &symptr->length );
585 symptr->howlen = e_number;
587 } else if (*patptr == '*') {
589 symptr->howlen = e_star;
591 } else if (*patptr == '[') {
592 char* lenptr = ++patptr;
593 symptr->howlen = e_number;
594 patptr = group_end( patptr, patend, ']' ) + 1;
595 /* what kind of [] is it? */
596 if (isDIGIT(*lenptr)) {
597 lenptr = get_num( lenptr, &symptr->length );
599 Perl_croak(aTHX_ "Malformed integer in [] in %s",
600 symptr->flags & FLAG_PACK ? "pack" : "unpack");
602 tempsym_t savsym = *symptr;
603 symptr->patend = patptr-1;
604 symptr->patptr = lenptr;
605 savsym.length = measure_struct(symptr);
609 symptr->howlen = e_no_len;
614 while (patptr < patend) {
615 if (isSPACE(*patptr))
617 else if (*patptr == '#') {
619 while (patptr < patend && *patptr != '\n')
624 if (*patptr == '/') {
625 symptr->flags |= FLAG_SLASH;
627 if (patptr < patend &&
628 (isDIGIT(*patptr) || *patptr == '*' || *patptr == '['))
629 Perl_croak(aTHX_ "'/' does not take a repeat count in %s",
630 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
636 /* at end - no count, no / */
637 symptr->howlen = e_no_len;
642 symptr->patptr = patptr;
646 symptr->patptr = patptr;
651 =for apidoc unpack_str
653 The engine implementing unpack() Perl function. Note: parameters strbeg, new_s
654 and ocnt are not used. This call should not be used, use unpackstring instead.
659 Perl_unpack_str(pTHX_ char *pat, register char *patend, register char *s, char *strbeg, char *strend, char **new_s, I32 ocnt, U32 flags)
661 tempsym_t sym = { 0 };
666 return unpack_rec(&sym, s, s, strend, NULL );
670 =for apidoc unpackstring
672 The engine implementing unpack() Perl function. C<unpackstring> puts the
673 extracted list items on the stack and returns the number of elements.
674 Issue C<PUTBACK> before and C<SPAGAIN> after the call to this function.
679 Perl_unpackstring(pTHX_ char *pat, register char *patend, register char *s, char *strend, U32 flags)
681 tempsym_t sym = { 0 };
686 return unpack_rec(&sym, s, s, strend, NULL );
691 S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, char *strend, char **new_s )
695 register I32 len = 0;
696 register I32 bits = 0;
699 I32 start_sp_offset = SP - PL_stack_base;
702 /* These must not be in registers: */
711 #if SHORTSIZE != SIZE16
713 unsigned short aushort;
718 #if LONGSIZE != SIZE32
719 unsigned long aulong;
724 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
725 long double aldouble;
734 const int bits_in_uv = 8 * sizeof(cuv);
737 bool unpack_only_one = (symptr->flags & FLAG_UNPACK_ONLY_ONE) != 0;
739 while (next_symbol(symptr)) {
740 datumtype = symptr->code;
741 /* do first one only unless in list context
742 / is implemented by unpacking the count, then poping it from the
743 stack, so must check that we're not in the middle of a / */
745 && (SP - PL_stack_base == start_sp_offset + 1)
746 && (datumtype != '/') ) /* XXX can this be omitted */
749 switch( howlen = symptr->howlen ){
752 len = symptr->length;
755 len = strend - strbeg; /* long enough */
760 beyond = s >= strend;
761 switch(TYPE_NO_ENDIANNESS(datumtype)) {
763 Perl_croak(aTHX_ "Invalid type '%c' in unpack", (int)TYPE_NO_MODIFIERS(datumtype) );
766 if (howlen == e_no_len)
767 len = 16; /* len is not specified */
775 char *ss = s; /* Move from register */
776 tempsym_t savsym = *symptr;
777 U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
778 symptr->flags |= group_modifiers;
779 symptr->patend = savsym.grpend;
783 symptr->patptr = savsym.grpbeg;
784 unpack_rec(symptr, ss, strbeg, strend, &ss );
785 if (ss == strend && savsym.howlen == e_star)
786 break; /* No way to continue */
790 symptr->flags &= ~group_modifiers;
791 savsym.flags = symptr->flags;
796 if (len > strend - strrelbeg)
797 Perl_croak(aTHX_ "'@' outside of string in unpack");
800 case 'X' | TYPE_IS_SHRIEKING:
801 if (!len) /* Avoid division by 0 */
803 len = (s - strbeg) % len;
806 if (len > s - strbeg)
807 Perl_croak(aTHX_ "'X' outside of string in unpack" );
810 case 'x' | TYPE_IS_SHRIEKING:
811 if (!len) /* Avoid division by 0 */
813 aint = (s - strbeg) % len;
814 if (aint) /* Other portable ways? */
820 if (len > strend - s)
821 Perl_croak(aTHX_ "'x' outside of string in unpack");
825 Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
830 if (len > strend - s)
834 sv = newSVpvn(s, len);
835 if (len > 0 && (datumtype == 'A' || datumtype == 'Z')) {
836 aptr = s; /* borrow register */
837 if (datumtype == 'Z') { /* 'Z' strips stuff after first null */
841 if (howlen == e_star) /* exact for 'Z*' */
842 len = s - SvPVX(sv) + 1;
844 else { /* 'A' strips both nulls and spaces */
845 s = SvPVX(sv) + len - 1;
846 while (s >= SvPVX(sv) && (!*s || isSPACE(*s)))
850 SvCUR_set(sv, s - SvPVX(sv));
851 s = aptr; /* unborrow register */
854 XPUSHs(sv_2mortal(sv));
858 if (howlen == e_star || len > (strend - s) * 8)
859 len = (strend - s) * 8;
862 Newz(601, PL_bitcount, 256, char);
863 for (bits = 1; bits < 256; bits++) {
864 if (bits & 1) PL_bitcount[bits]++;
865 if (bits & 2) PL_bitcount[bits]++;
866 if (bits & 4) PL_bitcount[bits]++;
867 if (bits & 8) PL_bitcount[bits]++;
868 if (bits & 16) PL_bitcount[bits]++;
869 if (bits & 32) PL_bitcount[bits]++;
870 if (bits & 64) PL_bitcount[bits]++;
871 if (bits & 128) PL_bitcount[bits]++;
875 cuv += PL_bitcount[*(unsigned char*)s++];
880 if (datumtype == 'b') {
888 if (bits & 128) cuv++;
895 sv = NEWSV(35, len + 1);
899 if (datumtype == 'b') {
901 for (len = 0; len < aint; len++) {
902 if (len & 7) /*SUPPRESS 595*/
906 *str++ = '0' + (bits & 1);
911 for (len = 0; len < aint; len++) {
916 *str++ = '0' + ((bits & 128) != 0);
920 XPUSHs(sv_2mortal(sv));
924 if (howlen == e_star || len > (strend - s) * 2)
925 len = (strend - s) * 2;
926 sv = NEWSV(35, len + 1);
930 if (datumtype == 'h') {
932 for (len = 0; len < aint; len++) {
937 *str++ = PL_hexdigit[bits & 15];
942 for (len = 0; len < aint; len++) {
947 *str++ = PL_hexdigit[(bits >> 4) & 15];
951 XPUSHs(sv_2mortal(sv));
954 if (len > strend - s)
957 if (len && unpack_only_one)
964 if (aint >= 128) /* fake up signed chars */
967 sv = newSViv((IV)aint);
968 PUSHs(sv_2mortal(sv));
970 else if (checksum > bits_in_uv)
977 unpack_C: /* unpack U will jump here if not UTF-8 */
979 symptr->flags &= ~FLAG_UNPACK_DO_UTF8;
982 if (len > strend - s)
992 if (len && unpack_only_one)
998 sv = newSViv((IV)auint);
999 PUSHs(sv_2mortal(sv));
1005 symptr->flags |= FLAG_UNPACK_DO_UTF8;
1008 if ((symptr->flags & FLAG_UNPACK_DO_UTF8) == 0)
1010 if (len > strend - s)
1013 if (len && unpack_only_one)
1018 while (len-- > 0 && s < strend) {
1020 auint = NATIVE_TO_UNI(utf8n_to_uvchr((U8*)s, strend - s, &alen, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANYUV));
1024 sv = newSVuv((UV)auint);
1025 PUSHs(sv_2mortal(sv));
1027 else if (checksum > bits_in_uv)
1028 cdouble += (NV)auint;
1033 case 's' | TYPE_IS_SHRIEKING:
1034 #if SHORTSIZE != SIZE16
1035 along = (strend - s) / sizeof(short);
1039 if (len && unpack_only_one)
1045 COPYNN(s, &ashort, sizeof(short));
1046 DO_BO_UNPACK(ashort, s);
1049 sv = newSViv((IV)ashort);
1050 PUSHs(sv_2mortal(sv));
1052 else if (checksum > bits_in_uv)
1053 cdouble += (NV)ashort;
1062 along = (strend - s) / SIZE16;
1066 if (len && unpack_only_one)
1073 DO_BO_UNPACK(ai16, 16);
1074 #if U16SIZE > SIZE16
1080 sv = newSViv((IV)ai16);
1081 PUSHs(sv_2mortal(sv));
1083 else if (checksum > bits_in_uv)
1084 cdouble += (NV)ai16;
1089 case 'S' | TYPE_IS_SHRIEKING:
1090 #if SHORTSIZE != SIZE16
1091 along = (strend - s) / sizeof(unsigned short);
1095 if (len && unpack_only_one)
1101 COPYNN(s, &aushort, sizeof(unsigned short));
1102 DO_BO_UNPACK(aushort, s);
1103 s += sizeof(unsigned short);
1105 sv = newSViv((UV)aushort);
1106 PUSHs(sv_2mortal(sv));
1108 else if (checksum > bits_in_uv)
1109 cdouble += (NV)aushort;
1120 along = (strend - s) / SIZE16;
1124 if (len && unpack_only_one)
1131 DO_BO_UNPACK(au16, 16);
1134 if (datumtype == 'n')
1135 au16 = PerlSock_ntohs(au16);
1138 if (datumtype == 'v')
1142 sv = newSViv((UV)au16);
1143 PUSHs(sv_2mortal(sv));
1145 else if (checksum > bits_in_uv)
1146 cdouble += (NV)au16;
1151 case 'v' | TYPE_IS_SHRIEKING:
1152 case 'n' | TYPE_IS_SHRIEKING:
1153 along = (strend - s) / SIZE16;
1157 if (len && unpack_only_one)
1166 if (datumtype == ('n' | TYPE_IS_SHRIEKING))
1167 ai16 = (I16)PerlSock_ntohs((U16)ai16);
1170 if (datumtype == ('v' | TYPE_IS_SHRIEKING))
1171 ai16 = (I16)vtohs((U16)ai16);
1174 sv = newSViv((IV)ai16);
1175 PUSHs(sv_2mortal(sv));
1177 else if (checksum > bits_in_uv)
1178 cdouble += (NV)ai16;
1184 case 'i' | TYPE_IS_SHRIEKING:
1185 along = (strend - s) / sizeof(int);
1189 if (len && unpack_only_one)
1195 Copy(s, &aint, 1, int);
1196 DO_BO_UNPACK(aint, i);
1199 sv = newSViv((IV)aint);
1200 PUSHs(sv_2mortal(sv));
1202 else if (checksum > bits_in_uv)
1203 cdouble += (NV)aint;
1209 case 'I' | TYPE_IS_SHRIEKING:
1210 along = (strend - s) / sizeof(unsigned int);
1214 if (len && unpack_only_one)
1220 Copy(s, &auint, 1, unsigned int);
1221 DO_BO_UNPACK(auint, i);
1222 s += sizeof(unsigned int);
1224 sv = newSVuv((UV)auint);
1225 PUSHs(sv_2mortal(sv));
1227 else if (checksum > bits_in_uv)
1228 cdouble += (NV)auint;
1234 along = (strend - s) / IVSIZE;
1238 if (len && unpack_only_one)
1244 Copy(s, &aiv, 1, IV);
1245 #if IVSIZE == INTSIZE
1246 DO_BO_UNPACK(aiv, i);
1247 #elif IVSIZE == LONGSIZE
1248 DO_BO_UNPACK(aiv, l);
1249 #elif defined(HAS_QUAD) && IVSIZE == U64SIZE
1250 DO_BO_UNPACK(aiv, 64);
1255 PUSHs(sv_2mortal(sv));
1257 else if (checksum > bits_in_uv)
1264 along = (strend - s) / UVSIZE;
1268 if (len && unpack_only_one)
1274 Copy(s, &auv, 1, UV);
1275 #if UVSIZE == INTSIZE
1276 DO_BO_UNPACK(auv, i);
1277 #elif UVSIZE == LONGSIZE
1278 DO_BO_UNPACK(auv, l);
1279 #elif defined(HAS_QUAD) && UVSIZE == U64SIZE
1280 DO_BO_UNPACK(auv, 64);
1285 PUSHs(sv_2mortal(sv));
1287 else if (checksum > bits_in_uv)
1293 case 'l' | TYPE_IS_SHRIEKING:
1294 #if LONGSIZE != SIZE32
1295 along = (strend - s) / sizeof(long);
1299 if (len && unpack_only_one)
1305 COPYNN(s, &along, sizeof(long));
1306 DO_BO_UNPACK(along, l);
1309 sv = newSViv((IV)along);
1310 PUSHs(sv_2mortal(sv));
1312 else if (checksum > bits_in_uv)
1313 cdouble += (NV)along;
1322 along = (strend - s) / SIZE32;
1326 if (len && unpack_only_one)
1333 DO_BO_UNPACK(ai32, 32);
1334 #if U32SIZE > SIZE32
1335 if (ai32 > 2147483647)
1340 sv = newSViv((IV)ai32);
1341 PUSHs(sv_2mortal(sv));
1343 else if (checksum > bits_in_uv)
1344 cdouble += (NV)ai32;
1349 case 'L' | TYPE_IS_SHRIEKING:
1350 #if LONGSIZE != SIZE32
1351 along = (strend - s) / sizeof(unsigned long);
1355 if (len && unpack_only_one)
1361 COPYNN(s, &aulong, sizeof(unsigned long));
1362 DO_BO_UNPACK(aulong, l);
1363 s += sizeof(unsigned long);
1365 sv = newSVuv((UV)aulong);
1366 PUSHs(sv_2mortal(sv));
1368 else if (checksum > bits_in_uv)
1369 cdouble += (NV)aulong;
1380 along = (strend - s) / SIZE32;
1384 if (len && unpack_only_one)
1391 DO_BO_UNPACK(au32, 32);
1394 if (datumtype == 'N')
1395 au32 = PerlSock_ntohl(au32);
1398 if (datumtype == 'V')
1402 sv = newSVuv((UV)au32);
1403 PUSHs(sv_2mortal(sv));
1405 else if (checksum > bits_in_uv)
1406 cdouble += (NV)au32;
1411 case 'V' | TYPE_IS_SHRIEKING:
1412 case 'N' | TYPE_IS_SHRIEKING:
1413 along = (strend - s) / SIZE32;
1417 if (len && unpack_only_one)
1426 if (datumtype == ('N' | TYPE_IS_SHRIEKING))
1427 ai32 = (I32)PerlSock_ntohl((U32)ai32);
1430 if (datumtype == ('V' | TYPE_IS_SHRIEKING))
1431 ai32 = (I32)vtohl((U32)ai32);
1434 sv = newSViv((IV)ai32);
1435 PUSHs(sv_2mortal(sv));
1437 else if (checksum > bits_in_uv)
1438 cdouble += (NV)ai32;
1444 along = (strend - s) / sizeof(char*);
1450 if (sizeof(char*) > strend - s)
1453 Copy(s, &aptr, 1, char*);
1454 DO_BO_UNPACK_P(aptr);
1457 /* newSVpv generates undef if aptr is NULL */
1458 PUSHs(sv_2mortal(newSVpv(aptr, 0)));
1462 if (len && unpack_only_one)
1470 while ((len > 0) && (s < strend)) {
1471 auv = (auv << 7) | (*s & 0x7f);
1472 /* UTF8_IS_XXXXX not right here - using constant 0x80 */
1473 if ((U8)(*s++) < 0x80) {
1476 PUSHs(sv_2mortal(sv));
1480 else if (++bytes >= sizeof(UV)) { /* promote to string */
1484 sv = Perl_newSVpvf(aTHX_ "%.*"UVf, (int)TYPE_DIGITS(UV), auv);
1485 while (s < strend) {
1486 sv = mul128(sv, (U8)(*s & 0x7f));
1487 if (!(*s++ & 0x80)) {
1496 PUSHs(sv_2mortal(sv));
1501 if ((s >= strend) && bytes)
1502 Perl_croak(aTHX_ "Unterminated compressed integer in unpack");
1506 if (symptr->howlen == e_star)
1507 Perl_croak(aTHX_ "'P' must have an explicit size in unpack");
1509 if (sizeof(char*) > strend - s)
1512 Copy(s, &aptr, 1, char*);
1513 DO_BO_UNPACK_P(aptr);
1516 /* newSVpvn generates undef if aptr is NULL */
1517 PUSHs(sv_2mortal(newSVpvn(aptr, len)));
1521 along = (strend - s) / sizeof(Quad_t);
1525 if (len && unpack_only_one)
1531 if (s + sizeof(Quad_t) > strend) {
1532 /* Surely this should never happen? NWC */
1536 Copy(s, &aquad, 1, Quad_t);
1537 DO_BO_UNPACK(aquad, 64);
1538 s += sizeof(Quad_t);
1541 if (aquad >= IV_MIN && aquad <= IV_MAX)
1542 sv = newSViv((IV)aquad);
1544 sv = newSVnv((NV)aquad);
1545 PUSHs(sv_2mortal(sv));
1547 else if (checksum > bits_in_uv)
1548 cdouble += (NV)aquad;
1554 along = (strend - s) / sizeof(Uquad_t);
1558 if (len && unpack_only_one)
1564 if (s + sizeof(Uquad_t) > strend)
1567 Copy(s, &auquad, 1, Uquad_t);
1568 DO_BO_UNPACK(auquad, 64);
1569 s += sizeof(Uquad_t);
1572 if (auquad <= UV_MAX)
1573 sv = newSVuv((UV)auquad);
1575 sv = newSVnv((NV)auquad);
1576 PUSHs(sv_2mortal(sv));
1578 else if (checksum > bits_in_uv)
1579 cdouble += (NV)auquad;
1585 /* float and double added gnb@melba.bby.oz.au 22/11/89 */
1587 along = (strend - s) / sizeof(float);
1591 if (len && unpack_only_one)
1597 Copy(s, &afloat, 1, float);
1598 DO_BO_UNPACK_N(afloat, float);
1601 sv = newSVnv((NV)afloat);
1602 PUSHs(sv_2mortal(sv));
1610 along = (strend - s) / sizeof(double);
1614 if (len && unpack_only_one)
1620 Copy(s, &adouble, 1, double);
1621 DO_BO_UNPACK_N(adouble, double);
1622 s += sizeof(double);
1624 sv = newSVnv((NV)adouble);
1625 PUSHs(sv_2mortal(sv));
1633 along = (strend - s) / NVSIZE;
1637 if (len && unpack_only_one)
1643 Copy(s, &anv, 1, NV);
1644 DO_BO_UNPACK_N(anv, NV);
1648 PUSHs(sv_2mortal(sv));
1655 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
1657 along = (strend - s) / LONG_DOUBLESIZE;
1661 if (len && unpack_only_one)
1667 Copy(s, &aldouble, 1, long double);
1668 DO_BO_UNPACK_N(aldouble, long double);
1669 s += LONG_DOUBLESIZE;
1671 sv = newSVnv((NV)aldouble);
1672 PUSHs(sv_2mortal(sv));
1674 else {cdouble += aldouble;
1681 * Initialise the decode mapping. By using a table driven
1682 * algorithm, the code will be character-set independent
1683 * (and just as fast as doing character arithmetic)
1685 if (PL_uudmap['M'] == 0) {
1688 for (i = 0; i < sizeof(PL_uuemap); i += 1)
1689 PL_uudmap[(U8)PL_uuemap[i]] = i;
1691 * Because ' ' and '`' map to the same value,
1692 * we need to decode them both the same.
1697 along = (strend - s) * 3 / 4;
1698 sv = NEWSV(42, along);
1701 while (s < strend && *s > ' ' && ISUUCHAR(*s)) {
1706 len = PL_uudmap[*(U8*)s++] & 077;
1708 if (s < strend && ISUUCHAR(*s))
1709 a = PL_uudmap[*(U8*)s++] & 077;
1712 if (s < strend && ISUUCHAR(*s))
1713 b = PL_uudmap[*(U8*)s++] & 077;
1716 if (s < strend && ISUUCHAR(*s))
1717 c = PL_uudmap[*(U8*)s++] & 077;
1720 if (s < strend && ISUUCHAR(*s))
1721 d = PL_uudmap[*(U8*)s++] & 077;
1724 hunk[0] = (char)((a << 2) | (b >> 4));
1725 hunk[1] = (char)((b << 4) | (c >> 2));
1726 hunk[2] = (char)((c << 6) | d);
1727 sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
1732 else /* possible checksum byte */
1733 if (s + 1 < strend && s[1] == '\n')
1736 XPUSHs(sv_2mortal(sv));
1741 if (strchr("fFdD", TYPE_NO_MODIFIERS(datumtype)) ||
1742 (checksum > bits_in_uv &&
1743 strchr("csSiIlLnNUvVqQjJ", TYPE_NO_MODIFIERS(datumtype))) ) {
1746 adouble = (NV) (1 << (checksum & 15));
1747 while (checksum >= 16) {
1751 while (cdouble < 0.0)
1753 cdouble = Perl_modf(cdouble / adouble, &trouble) * adouble;
1754 sv = newSVnv(cdouble);
1757 if (checksum < bits_in_uv) {
1758 UV mask = ((UV)1 << checksum) - 1;
1763 XPUSHs(sv_2mortal(sv));
1767 if (symptr->flags & FLAG_SLASH){
1768 if (SP - PL_stack_base - start_sp_offset <= 0)
1769 Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
1770 if( next_symbol(symptr) ){
1771 if( symptr->howlen == e_number )
1772 Perl_croak(aTHX_ "Count after length/code in unpack" );
1774 /* ...end of char buffer then no decent length available */
1775 Perl_croak(aTHX_ "length/code after end of string in unpack" );
1777 /* take top of stack (hope it's numeric) */
1780 Perl_croak(aTHX_ "Negative '/' count in unpack" );
1783 Perl_croak(aTHX_ "Code missing after '/' in unpack" );
1785 datumtype = symptr->code;
1793 return SP - PL_stack_base - start_sp_offset;
1800 I32 gimme = GIMME_V;
1803 register char *pat = SvPV(left, llen);
1804 #ifdef PACKED_IS_OCTETS
1805 /* Packed side is assumed to be octets - so force downgrade if it
1806 has been UTF-8 encoded by accident
1808 register char *s = SvPVbyte(right, rlen);
1810 register char *s = SvPV(right, rlen);
1812 char *strend = s + rlen;
1813 register char *patend = pat + llen;
1817 cnt = unpackstring(pat, patend, s, strend,
1818 ((gimme == G_SCALAR) ? FLAG_UNPACK_ONLY_ONE : 0)
1819 | (DO_UTF8(right) ? FLAG_UNPACK_DO_UTF8 : 0));
1822 if ( !cnt && gimme == G_SCALAR )
1823 PUSHs(&PL_sv_undef);
1828 S_doencodes(pTHX_ register SV *sv, register char *s, register I32 len)
1832 *hunk = PL_uuemap[len];
1833 sv_catpvn(sv, hunk, 1);
1836 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
1837 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)))];
1838 hunk[2] = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
1839 hunk[3] = PL_uuemap[(077 & (s[2] & 077))];
1840 sv_catpvn(sv, hunk, 4);
1845 char r = (len > 1 ? s[1] : '\0');
1846 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
1847 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((r >> 4) & 017)))];
1848 hunk[2] = PL_uuemap[(077 & ((r << 2) & 074))];
1849 hunk[3] = PL_uuemap[0];
1850 sv_catpvn(sv, hunk, 4);
1852 sv_catpvn(sv, "\n", 1);
1856 S_is_an_int(pTHX_ char *s, STRLEN l)
1859 SV *result = newSVpvn(s, l);
1860 char *result_c = SvPV(result, n_a); /* convenience */
1861 char *out = result_c;
1871 SvREFCNT_dec(result);
1894 SvREFCNT_dec(result);
1900 SvCUR_set(result, out - result_c);
1904 /* pnum must be '\0' terminated */
1906 S_div128(pTHX_ SV *pnum, bool *done)
1909 char *s = SvPV(pnum, len);
1918 i = m * 10 + (*t - '0');
1920 r = (i >> 7); /* r < 10 */
1927 SvCUR_set(pnum, (STRLEN) (t - s));
1934 =for apidoc pack_cat
1936 The engine implementing pack() Perl function. Note: parameters next_in_list and
1937 flags are not used. This call should not be used; use packlist instead.
1943 Perl_pack_cat(pTHX_ SV *cat, char *pat, register char *patend, register SV **beglist, SV **endlist, SV ***next_in_list, U32 flags)
1945 tempsym_t sym = { 0 };
1947 sym.patend = patend;
1948 sym.flags = FLAG_PACK;
1950 (void)pack_rec( cat, &sym, beglist, endlist );
1955 =for apidoc packlist
1957 The engine implementing pack() Perl function.
1963 Perl_packlist(pTHX_ SV *cat, char *pat, register char *patend, register SV **beglist, SV **endlist )
1965 tempsym_t sym = { 0 };
1967 sym.patend = patend;
1968 sym.flags = FLAG_PACK;
1970 (void)pack_rec( cat, &sym, beglist, endlist );
1976 S_pack_rec(pTHX_ SV *cat, register tempsym_t* symptr, register SV **beglist, SV **endlist )
1980 register I32 len = 0;
1983 static char null10[] = {0,0,0,0,0,0,0,0,0,0};
1984 static char *space10 = " ";
1987 /* These must not be in registers: */
1997 #if SHORTSIZE != SIZE16
1999 unsigned short aushort;
2003 #if LONGSIZE != SIZE32
2005 unsigned long aulong;
2010 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
2011 long double aldouble;
2017 int strrelbeg = SvCUR(cat);
2018 tempsym_t lookahead;
2020 items = endlist - beglist;
2021 found = next_symbol( symptr );
2023 #ifndef PACKED_IS_OCTETS
2024 if (symptr->level == 0 && found && symptr->code == 'U' ){
2030 SV *lengthcode = Nullsv;
2031 #define NEXTFROM ( lengthcode ? lengthcode : items-- > 0 ? *beglist++ : &PL_sv_no)
2033 I32 datumtype = symptr->code;
2036 switch( howlen = symptr->howlen ){
2039 len = symptr->length;
2042 len = strchr("@Xxu", TYPE_NO_MODIFIERS(datumtype)) ? 0 : items;
2046 /* Look ahead for next symbol. Do we have code/code? */
2047 lookahead = *symptr;
2048 found = next_symbol(&lookahead);
2049 if ( symptr->flags & FLAG_SLASH ) {
2051 if ( 0 == strchr( "aAZ", lookahead.code ) ||
2052 e_star != lookahead.howlen )
2053 Perl_croak(aTHX_ "'/' must be followed by 'a*', 'A*' or 'Z*' in pack");
2054 lengthcode = sv_2mortal(newSViv(sv_len(items > 0
2055 ? *beglist : &PL_sv_no)
2056 + (lookahead.code == 'Z' ? 1 : 0)));
2058 Perl_croak(aTHX_ "Code missing after '/' in pack");
2062 switch(TYPE_NO_ENDIANNESS(datumtype)) {
2064 Perl_croak(aTHX_ "Invalid type '%c' in pack", (int)TYPE_NO_MODIFIERS(datumtype));
2066 Perl_croak(aTHX_ "'%%' may not be used in pack");
2068 len += strrelbeg - SvCUR(cat);
2077 tempsym_t savsym = *symptr;
2078 U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
2079 symptr->flags |= group_modifiers;
2080 symptr->patend = savsym.grpend;
2083 symptr->patptr = savsym.grpbeg;
2084 beglist = pack_rec(cat, symptr, beglist, endlist );
2085 if (savsym.howlen == e_star && beglist == endlist)
2086 break; /* No way to continue */
2088 symptr->flags &= ~group_modifiers;
2089 lookahead.flags = symptr->flags;
2093 case 'X' | TYPE_IS_SHRIEKING:
2094 if (!len) /* Avoid division by 0 */
2096 len = (SvCUR(cat)) % len;
2100 if ((I32)SvCUR(cat) < len)
2101 Perl_croak(aTHX_ "'X' outside of string in pack");
2105 case 'x' | TYPE_IS_SHRIEKING:
2106 if (!len) /* Avoid division by 0 */
2108 aint = (SvCUR(cat)) % len;
2109 if (aint) /* Other portable ways? */
2118 sv_catpvn(cat, null10, 10);
2121 sv_catpvn(cat, null10, len);
2127 aptr = SvPV(fromstr, fromlen);
2128 if (howlen == e_star) {
2130 if (datumtype == 'Z')
2133 if ((I32)fromlen >= len) {
2134 sv_catpvn(cat, aptr, len);
2135 if (datumtype == 'Z')
2136 *(SvEND(cat)-1) = '\0';
2139 sv_catpvn(cat, aptr, fromlen);
2141 if (datumtype == 'A') {
2143 sv_catpvn(cat, space10, 10);
2146 sv_catpvn(cat, space10, len);
2150 sv_catpvn(cat, null10, 10);
2153 sv_catpvn(cat, null10, len);
2165 str = SvPV(fromstr, fromlen);
2166 if (howlen == e_star)
2169 SvCUR(cat) += (len+7)/8;
2170 SvGROW(cat, SvCUR(cat) + 1);
2171 aptr = SvPVX(cat) + aint;
2172 if (len > (I32)fromlen)
2176 if (datumtype == 'B') {
2177 for (len = 0; len++ < aint;) {
2178 items |= *str++ & 1;
2182 *aptr++ = items & 0xff;
2188 for (len = 0; len++ < aint;) {
2194 *aptr++ = items & 0xff;
2200 if (datumtype == 'B')
2201 items <<= 7 - (aint & 7);
2203 items >>= 7 - (aint & 7);
2204 *aptr++ = items & 0xff;
2206 str = SvPVX(cat) + SvCUR(cat);
2221 str = SvPV(fromstr, fromlen);
2222 if (howlen == e_star)
2225 SvCUR(cat) += (len+1)/2;
2226 SvGROW(cat, SvCUR(cat) + 1);
2227 aptr = SvPVX(cat) + aint;
2228 if (len > (I32)fromlen)
2232 if (datumtype == 'H') {
2233 for (len = 0; len++ < aint;) {
2235 items |= ((*str++ & 15) + 9) & 15;
2237 items |= *str++ & 15;
2241 *aptr++ = items & 0xff;
2247 for (len = 0; len++ < aint;) {
2249 items |= (((*str++ & 15) + 9) & 15) << 4;
2251 items |= (*str++ & 15) << 4;
2255 *aptr++ = items & 0xff;
2261 *aptr++ = items & 0xff;
2262 str = SvPVX(cat) + SvCUR(cat);
2273 switch (TYPE_NO_MODIFIERS(datumtype)) {
2275 aint = SvIV(fromstr);
2276 if ((aint < 0 || aint > 255) &&
2278 Perl_warner(aTHX_ packWARN(WARN_PACK),
2279 "Character in 'C' format wrapped in pack");
2281 sv_catpvn(cat, &achar, sizeof(char));
2284 aint = SvIV(fromstr);
2285 if ((aint < -128 || aint > 127) &&
2287 Perl_warner(aTHX_ packWARN(WARN_PACK),
2288 "Character in 'c' format wrapped in pack" );
2290 sv_catpvn(cat, &achar, sizeof(char));
2298 auint = UNI_TO_NATIVE(SvUV(fromstr));
2299 SvGROW(cat, SvCUR(cat) + UTF8_MAXLEN + 1);
2301 (char*)uvchr_to_utf8_flags((U8*)SvEND(cat),
2304 0 : UNICODE_ALLOW_ANY)
2309 /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */
2314 /* VOS does not automatically map a floating-point overflow
2315 during conversion from double to float into infinity, so we
2316 do it by hand. This code should either be generalized for
2317 any OS that needs it, or removed if and when VOS implements
2318 posix-976 (suggestion to support mapping to infinity).
2319 Paul.Green@stratus.com 02-04-02. */
2320 if (SvNV(fromstr) > FLT_MAX)
2321 afloat = _float_constants[0]; /* single prec. inf. */
2322 else if (SvNV(fromstr) < -FLT_MAX)
2323 afloat = _float_constants[0]; /* single prec. inf. */
2324 else afloat = (float)SvNV(fromstr);
2326 # if defined(VMS) && !defined(__IEEE_FP)
2327 /* IEEE fp overflow shenanigans are unavailable on VAX and optional
2328 * on Alpha; fake it if we don't have them.
2330 if (SvNV(fromstr) > FLT_MAX)
2332 else if (SvNV(fromstr) < -FLT_MAX)
2334 else afloat = (float)SvNV(fromstr);
2336 afloat = (float)SvNV(fromstr);
2339 DO_BO_PACK_N(afloat, float);
2340 sv_catpvn(cat, (char *)&afloat, sizeof (float));
2347 /* VOS does not automatically map a floating-point overflow
2348 during conversion from long double to double into infinity,
2349 so we do it by hand. This code should either be generalized
2350 for any OS that needs it, or removed if and when VOS
2351 implements posix-976 (suggestion to support mapping to
2352 infinity). Paul.Green@stratus.com 02-04-02. */
2353 if (SvNV(fromstr) > DBL_MAX)
2354 adouble = _double_constants[0]; /* double prec. inf. */
2355 else if (SvNV(fromstr) < -DBL_MAX)
2356 adouble = _double_constants[0]; /* double prec. inf. */
2357 else adouble = (double)SvNV(fromstr);
2359 # if defined(VMS) && !defined(__IEEE_FP)
2360 /* IEEE fp overflow shenanigans are unavailable on VAX and optional
2361 * on Alpha; fake it if we don't have them.
2363 if (SvNV(fromstr) > DBL_MAX)
2365 else if (SvNV(fromstr) < -DBL_MAX)
2367 else adouble = (double)SvNV(fromstr);
2369 adouble = (double)SvNV(fromstr);
2372 DO_BO_PACK_N(adouble, double);
2373 sv_catpvn(cat, (char *)&adouble, sizeof (double));
2377 Zero(&anv, 1, NV); /* can be long double with unused bits */
2380 anv = SvNV(fromstr);
2381 DO_BO_PACK_N(anv, NV);
2382 sv_catpvn(cat, (char *)&anv, NVSIZE);
2385 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
2387 /* long doubles can have unused bits, which may be nonzero */
2388 Zero(&aldouble, 1, long double);
2391 aldouble = (long double)SvNV(fromstr);
2392 DO_BO_PACK_N(aldouble, long double);
2393 sv_catpvn(cat, (char *)&aldouble, LONG_DOUBLESIZE);
2397 case 'n' | TYPE_IS_SHRIEKING:
2401 ai16 = (I16)SvIV(fromstr);
2403 ai16 = PerlSock_htons(ai16);
2408 case 'v' | TYPE_IS_SHRIEKING:
2412 ai16 = (I16)SvIV(fromstr);
2419 case 'S' | TYPE_IS_SHRIEKING:
2420 #if SHORTSIZE != SIZE16
2424 aushort = SvUV(fromstr);
2425 DO_BO_PACK(aushort, s);
2426 sv_catpvn(cat, (char *)&aushort, sizeof(unsigned short));
2437 au16 = (U16)SvUV(fromstr);
2438 DO_BO_PACK(au16, 16);
2444 case 's' | TYPE_IS_SHRIEKING:
2445 #if SHORTSIZE != SIZE16
2449 ashort = SvIV(fromstr);
2450 DO_BO_PACK(ashort, s);
2451 sv_catpvn(cat, (char *)&ashort, sizeof(short));
2461 ai16 = (I16)SvIV(fromstr);
2462 DO_BO_PACK(ai16, 16);
2467 case 'I' | TYPE_IS_SHRIEKING:
2470 auint = SvUV(fromstr);
2471 DO_BO_PACK(auint, i);
2472 sv_catpvn(cat, (char*)&auint, sizeof(unsigned int));
2478 aiv = SvIV(fromstr);
2479 #if IVSIZE == INTSIZE
2481 #elif IVSIZE == LONGSIZE
2483 #elif defined(HAS_QUAD) && IVSIZE == U64SIZE
2484 DO_BO_PACK(aiv, 64);
2486 sv_catpvn(cat, (char*)&aiv, IVSIZE);
2492 auv = SvUV(fromstr);
2493 #if UVSIZE == INTSIZE
2495 #elif UVSIZE == LONGSIZE
2497 #elif defined(HAS_QUAD) && UVSIZE == U64SIZE
2498 DO_BO_PACK(auv, 64);
2500 sv_catpvn(cat, (char*)&auv, UVSIZE);
2506 anv = SvNV(fromstr);
2509 Perl_croak(aTHX_ "Cannot compress negative numbers in pack");
2511 /* 0xFFFFFFFFFFFFFFFF may cast to 18446744073709551616.0,
2512 which is == UV_MAX_P1. IOK is fine (instead of UV_only), as
2513 any negative IVs will have already been got by the croak()
2514 above. IOK is untrue for fractions, so we test them
2515 against UV_MAX_P1. */
2516 if (SvIOK(fromstr) || anv < UV_MAX_P1)
2518 char buf[(sizeof(UV)*8)/7+1];
2519 char *in = buf + sizeof(buf);
2520 UV auv = SvUV(fromstr);
2523 *--in = (char)((auv & 0x7f) | 0x80);
2526 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2527 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
2529 else if (SvPOKp(fromstr)) { /* decimal string arithmetics */
2530 char *from, *result, *in;
2535 /* Copy string and check for compliance */
2536 from = SvPV(fromstr, len);
2537 if ((norm = is_an_int(from, len)) == NULL)
2538 Perl_croak(aTHX_ "Can only compress unsigned integers in pack");
2540 New('w', result, len, char);
2544 *--in = div128(norm, &done) | 0x80;
2545 result[len - 1] &= 0x7F; /* clear continue bit */
2546 sv_catpvn(cat, in, (result + len) - in);
2548 SvREFCNT_dec(norm); /* free norm */
2550 else if (SvNOKp(fromstr)) {
2551 /* 10**NV_MAX_10_EXP is the largest power of 10
2552 so 10**(NV_MAX_10_EXP+1) is definately unrepresentable
2553 given 10**(NV_MAX_10_EXP+1) == 128 ** x solve for x:
2554 x = (NV_MAX_10_EXP+1) * log (10) / log (128)
2555 And with that many bytes only Inf can overflow.
2556 Some C compilers are strict about integral constant
2557 expressions so we conservatively divide by a slightly
2558 smaller integer instead of multiplying by the exact
2559 floating-point value.
2561 #ifdef NV_MAX_10_EXP
2562 /* char buf[1 + (int)((NV_MAX_10_EXP + 1) * 0.47456)]; -- invalid C */
2563 char buf[1 + (int)((NV_MAX_10_EXP + 1) / 2)]; /* valid C */
2565 /* char buf[1 + (int)((308 + 1) * 0.47456)]; -- invalid C */
2566 char buf[1 + (int)((308 + 1) / 2)]; /* valid C */
2568 char *in = buf + sizeof(buf);
2570 anv = Perl_floor(anv);
2572 NV next = Perl_floor(anv / 128);
2573 if (in <= buf) /* this cannot happen ;-) */
2574 Perl_croak(aTHX_ "Cannot compress integer in pack");
2575 *--in = (unsigned char)(anv - (next * 128)) | 0x80;
2578 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2579 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
2582 char *from, *result, *in;
2587 /* Copy string and check for compliance */
2588 from = SvPV(fromstr, len);
2589 if ((norm = is_an_int(from, len)) == NULL)
2590 Perl_croak(aTHX_ "Can only compress unsigned integers in pack");
2592 New('w', result, len, char);
2596 *--in = div128(norm, &done) | 0x80;
2597 result[len - 1] &= 0x7F; /* clear continue bit */
2598 sv_catpvn(cat, in, (result + len) - in);
2600 SvREFCNT_dec(norm); /* free norm */
2605 case 'i' | TYPE_IS_SHRIEKING:
2608 aint = SvIV(fromstr);
2609 DO_BO_PACK(aint, i);
2610 sv_catpvn(cat, (char*)&aint, sizeof(int));
2613 case 'N' | TYPE_IS_SHRIEKING:
2617 au32 = SvUV(fromstr);
2619 au32 = PerlSock_htonl(au32);
2624 case 'V' | TYPE_IS_SHRIEKING:
2628 au32 = SvUV(fromstr);
2635 case 'L' | TYPE_IS_SHRIEKING:
2636 #if LONGSIZE != SIZE32
2640 aulong = SvUV(fromstr);
2641 DO_BO_PACK(aulong, l);
2642 sv_catpvn(cat, (char *)&aulong, sizeof(unsigned long));
2653 au32 = SvUV(fromstr);
2654 DO_BO_PACK(au32, 32);
2659 case 'l' | TYPE_IS_SHRIEKING:
2660 #if LONGSIZE != SIZE32
2664 along = SvIV(fromstr);
2665 DO_BO_PACK(along, l);
2666 sv_catpvn(cat, (char *)&along, sizeof(long));
2676 ai32 = SvIV(fromstr);
2677 DO_BO_PACK(ai32, 32);
2685 auquad = (Uquad_t)SvUV(fromstr);
2686 DO_BO_PACK(auquad, 64);
2687 sv_catpvn(cat, (char*)&auquad, sizeof(Uquad_t));
2693 aquad = (Quad_t)SvIV(fromstr);
2694 DO_BO_PACK(aquad, 64);
2695 sv_catpvn(cat, (char*)&aquad, sizeof(Quad_t));
2700 len = 1; /* assume SV is correct length */
2705 if (fromstr == &PL_sv_undef)
2709 /* XXX better yet, could spirit away the string to
2710 * a safe spot and hang on to it until the result
2711 * of pack() (and all copies of the result) are
2714 if (ckWARN(WARN_PACK) && (SvTEMP(fromstr)
2715 || (SvPADTMP(fromstr)
2716 && !SvREADONLY(fromstr))))
2718 Perl_warner(aTHX_ packWARN(WARN_PACK),
2719 "Attempt to pack pointer to temporary value");
2721 if (SvPOK(fromstr) || SvNIOK(fromstr))
2722 aptr = SvPV(fromstr,n_a);
2724 aptr = SvPV_force(fromstr,n_a);
2727 sv_catpvn(cat, (char*)&aptr, sizeof(char*));
2732 aptr = SvPV(fromstr, fromlen);
2733 SvGROW(cat, fromlen * 4 / 3);
2738 while (fromlen > 0) {
2741 if ((I32)fromlen > len)
2745 doencodes(cat, aptr, todo);
2751 *symptr = lookahead;
2760 dSP; dMARK; dORIGMARK; dTARGET;
2761 register SV *cat = TARG;
2763 register char *pat = SvPVx(*++MARK, fromlen);
2764 register char *patend = pat + fromlen;
2767 sv_setpvn(cat, "", 0);
2769 packlist(cat, pat, patend, MARK, SP + 1);
2779 * c-indentation-style: bsd
2781 * indent-tabs-mode: t
2784 * vim: expandtab shiftwidth=4: