summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1998-05-15 02:15:25 +0000
committerGurusamy Sarathy <gsar@cpan.org>1998-05-15 02:15:25 +0000
commit6ff81951f79dec32e15a779d288c1047f0e4fefb (patch)
tree53c645778f7a018e0bd74a2ec2fe9c64833ea13d /mg.c
parent48c036b1eb8f866b948f33704ee6152323a5aad9 (diff)
downloadperl-6ff81951f79dec32e15a779d288c1047f0e4fefb.tar.gz
[win32] merge changes#906,907,909,910 from maintbranch
p4raw-link: @910 on //depot/maint-5.004/perl: ae941ac0da8f453f0d31df7b7293e50b3e5a46f1 p4raw-link: @909 on //depot/maint-5.004/perl: 8b3d696ffd11cf2e49f6eaa575b829ab0a55352d p4raw-link: @907 on //depot/maint-5.004/perl: 3cb3c1abada5765ba4166ebe59e2e20d737ec21b p4raw-link: @906 on //depot/maint-5.004/perl: ae389c8a29b487f4434c465442dfb611507a4a38 p4raw-id: //depot/win32/perl@977
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c107
1 files changed, 106 insertions, 1 deletions
diff --git a/mg.c b/mg.c
index 108644a6de..268ec8081c 100644
--- a/mg.c
+++ b/mg.c
@@ -946,11 +946,33 @@ magic_setamagic(SV *sv, MAGIC *mg)
#endif /* OVERLOAD */
int
+magic_getnkeys(SV *sv, MAGIC *mg)
+{
+ HV *hv = (HV*)LvTARG(sv);
+ HE *entry;
+ I32 i = 0;
+
+ if (hv) {
+ (void) hv_iterinit(hv);
+ if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P'))
+ i = HvKEYS(hv);
+ else {
+ /*SUPPRESS 560*/
+ while (entry = hv_iternext(hv)) {
+ i++;
+ }
+ }
+ }
+
+ sv_setiv(sv, (IV)i);
+ return 0;
+}
+
+int
magic_setnkeys(SV *sv, MAGIC *mg)
{
if (LvTARG(sv)) {
hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
- LvTARG(sv) = Nullsv; /* Don't allow a ref to reassign this. */
}
return 0;
}
@@ -1219,6 +1241,23 @@ magic_setglob(SV *sv, MAGIC *mg)
}
int
+magic_getsubstr(SV *sv, MAGIC *mg)
+{
+ STRLEN len;
+ SV *lsv = LvTARG(sv);
+ char *tmps = SvPV(lsv,len);
+ I32 offs = LvTARGOFF(sv);
+ I32 rem = LvTARGLEN(sv);
+
+ if (offs > len)
+ offs = len;
+ if (rem + offs > len)
+ rem = len - offs;
+ sv_setpvn(sv, tmps + offs, (STRLEN)rem);
+ return 0;
+}
+
+int
magic_setsubstr(SV *sv, MAGIC *mg)
{
STRLEN len;
@@ -1254,6 +1293,72 @@ magic_settaint(SV *sv, MAGIC *mg)
}
int
+magic_getvec(SV *sv, MAGIC *mg)
+{
+ SV *lsv = LvTARG(sv);
+ unsigned char *s;
+ unsigned long retnum;
+ STRLEN lsvlen;
+ I32 len;
+ I32 offset;
+ I32 size;
+
+ if (!lsv) {
+ SvOK_off(sv);
+ return 0;
+ }
+ s = (unsigned char *) SvPV(lsv, lsvlen);
+ offset = LvTARGOFF(sv);
+ size = LvTARGLEN(sv);
+ len = (offset + size + 7) / 8;
+
+ /* Copied from pp_vec() */
+
+ if (len > lsvlen) {
+ if (size <= 8)
+ retnum = 0;
+ else {
+ offset >>= 3;
+ if (size == 16) {
+ if (offset >= lsvlen)
+ retnum = 0;
+ else
+ retnum = (unsigned long) s[offset] << 8;
+ }
+ else if (size == 32) {
+ if (offset >= lsvlen)
+ retnum = 0;
+ else if (offset + 1 >= lsvlen)
+ retnum = (unsigned long) s[offset] << 24;
+ else if (offset + 2 >= lsvlen)
+ retnum = ((unsigned long) s[offset] << 24) +
+ ((unsigned long) s[offset + 1] << 16);
+ else
+ retnum = ((unsigned long) s[offset] << 24) +
+ ((unsigned long) s[offset + 1] << 16) +
+ (s[offset + 2] << 8);
+ }
+ }
+ }
+ else if (size < 8)
+ retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
+ else {
+ offset >>= 3;
+ if (size == 8)
+ retnum = s[offset];
+ else if (size == 16)
+ retnum = ((unsigned long) s[offset] << 8) + s[offset+1];
+ else if (size == 32)
+ retnum = ((unsigned long) s[offset] << 24) +
+ ((unsigned long) s[offset + 1] << 16) +
+ (s[offset + 2] << 8) + s[offset+3];
+ }
+
+ sv_setuv(sv, (UV)retnum);
+ return 0;
+}
+
+int
magic_setvec(SV *sv, MAGIC *mg)
{
do_vecset(sv); /* XXX slurp this routine */