Commit | Line | Data |
e98cedbf |
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 |