1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
#ifndef STR_H__
#define STR_H__
// $Id: str.h,v 1.7 2002/07/04 04:52:29 hio Exp $
// BUF_MALLOC : use malloc()
// (undef) : use SV* buffer directly
//#define BUF_MALLOC
class SV_Buf
{
private:
#ifndef BUF_MALLOC
SV* sv;
#endif
STRLEN alloc_len;
unsigned char* dst;
unsigned char* dst_begin;
public:
#ifndef BUF_MALLOC
SV_Buf(STRLEN len) : alloc_len(len)
{
sv = newSVpvn("",0);
STRLEN alen = alloc_len+1;
//fprintf(stderr,"sv = %#08x, len = %d\n",sv,alen);
SvGROW(sv,alen);
dst = (unsigned char*)SvPV(sv,alen);
dst_begin = dst;
}
#else
SV_Buf(STRLEN len) : alloc_len(len)
{
dst = (unsigned char*)malloc(alloc_len+1);
dst_begin = dst;
fprintf(stderr,"malloc = %#08x\n",dst_begin);
}
~SV_Buf()
{
free(dst_begin);
}
#endif
STRLEN getLength(){ return dst-dst_begin; }
#ifndef BUF_MALLOC
void setLength(){ SvCUR_set(sv,dst-dst_begin); }
#else
void setLength(){}
#endif
unsigned char* getBegin(){ return dst_begin; }
SV* getSv()
{
#ifndef BUF_MALLOC
return sv;
#else
return newSVpvn((char*)dst_begin,dst-dst_begin);
#endif
}
inline void append(unsigned char ch)
{ // same as append_ch
checkbuf(1);
*dst++ = ch;
}
inline void append_ch(unsigned char ch)
{
checkbuf(1);
*dst++ = ch;
}
inline void append_ch2(unsigned short ch)
{
checkbuf(2);
*(unsigned short*)dst = ch;
dst += 2;
}
inline void append_ch3(int ch)
{
checkbuf(4);
*(int*)dst = ch;
dst += 3;
}
inline void append_ch4(int ch)
{
checkbuf(4);
*(int*)dst = ch;
dst += 4;
}
inline void append_ch5(const unsigned char* src)
{
checkbuf(5);
memcpy(dst,src,5);
dst += 5;
}
inline void append(const unsigned char* src, int len)
{
checkbuf(len);
memcpy(dst,src,len);
dst += len;
}
// entity reference ���ɲ�
inline void append_entityref(unsigned long ucs)
{
char buf[32];
register int write_len = snprintf(buf,32,"&#%lu;",ucs);
if( write_len!=-1 && write_len<32 )
{
append((unsigned char*)buf,write_len);
}else
{ // ���Ԥ��륳�Ȥʤ�Ƥʤ��Ȼפ����ɡ�.
// -1��glibc2.0.6����, 2.1�ʹߤ�ɬ�פʥ�����
append_ch('?');
}
}
void checkbuf(STRLEN len)
{
#ifdef TEST
if( len==0 )
{
fprintf(stderr,"SV_Buf.checkbuf, check length 0.\n");
}
#endif
if( (dst-dst_begin)+len>=alloc_len )
{
STRLEN now_len = dst-dst_begin;
STRLEN new_len = (alloc_len+len)*2;
#ifdef TEST
fprintf(stderr,"<<SV_Buf.realloc>> %d+%d/%d => %d\n",now_len,len,alloc_len,new_len);
#endif
#ifndef BUF_MALLOC
setLength();
STRLEN alen = new_len+1;
SvGROW(sv,alen);
STRLEN curlen;
dst_begin = (unsigned char*)SvPV(sv,curlen);
#else
unsigned char* buf = (unsigned char*)malloc(new_len+1);
memcpy(buf,dst_begin,now_len);
free(dst_begin);
dst_begin = buf;
#endif
alloc_len = new_len;
dst = dst_begin + now_len;
}
}
};
#endif
|