initial import of Devel-Size 0.01 from CPAN
[p5sagit/Devel-Size.git] / Size.xs
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 UV thing_size(SV *orig_thing) {
6   SV *thing = orig_thing;
7   UV total_size = sizeof(SV);
8   
9   /* If they passed us a reference then dereference it. This is the
10      only way we can check the sizes of arrays and hashes */
11   if (SvOK(thing) && SvROK(thing)) {
12     thing = SvRV(thing);
13   }
14   
15   switch (SvTYPE(thing)) {
16     /* Is it undef? */
17   case SVt_NULL:
18     break;
19     /* Just a plain integer. This will be differently sized depending
20        on whether purify's been compiled in */
21   case SVt_IV:
22 #ifdef PURIFY
23     total_size += sizeof(sizeof(XPVIV));
24 #else
25     total_size += sizeof(IV);
26 #endif
27     break;
28     /* Is it a float? Like the int, it depends on purify */
29   case SVt_NV:
30 #ifdef PURIFY
31     total_size += sizeof(sizeof(XPVNV));
32 #else
33     total_size += sizeof(NV);
34 #endif
35     break;
36     /* Is it a reference? */
37   case SVt_RV:
38     total_size += sizeof(XRV);
39     break;
40     /* How about a plain string? In which case we need to add in how
41        much has been allocated */
42   case SVt_PV:
43     total_size += sizeof(XPV);
44     total_size += SvLEN(thing);
45     break;
46     /* A string with an integer part? */
47   case SVt_PVIV:
48     total_size += sizeof(XPVIV);
49     total_size += SvLEN(thing);
50     break;
51     /* A string with a float part? */
52   case SVt_PVNV:
53     total_size += sizeof(XPVNV);
54     total_size += SvLEN(thing);
55     break;
56   case SVt_PVMG:
57     croak("Not yet");
58     break;
59   case SVt_PVBM:
60     croak("Not yet");
61     break;
62   case SVt_PVLV:
63     croak("Not yet");
64     break;
65     /* How much space is dedicated to the array? Not counting the
66        elements in the array, mind, just the array itself */
67   case SVt_PVAV:
68     total_size += sizeof(XPVAV);
69     /* Is there anything in the array? */
70     if (AvMAX(thing) != -1) {
71       total_size += sizeof(SV *) * AvMAX(thing);
72     }
73     /* Add in the bits on the other side of the beginning */
74     total_size += (sizeof(SV *) * (AvARRAY(thing) - AvALLOC(thing)));
75     /* Is there something hanging off the arylen element? */
76     if (AvARYLEN(thing)) {
77       total_size += thing_size(AvARYLEN(thing));
78     }
79     break;
80   case SVt_PVHV:
81     croak("Not yet");
82     break;
83   case SVt_PVCV:
84     croak("Not yet");
85     break;
86   case SVt_PVGV:
87     croak("Not yet");
88     break;
89   case SVt_PVFM:
90     croak("Not yet");
91     break;
92   case SVt_PVIO:
93     croak("Not yet");
94     break;
95   default:
96     croak("Unknown variable type");
97   }
98   return total_size;
99 }
100
101
102 MODULE = Devel::Size            PACKAGE = Devel::Size           
103
104 UV
105 size(SV *orig_thing)
106 CODE:
107 {
108   RETVAL = thing_size(orig_thing);
109 }
110 OUTPUT:
111   RETVAL