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