summaryrefslogtreecommitdiff
path: root/cpan/dist/Unicode-Japanese/str.h
blob: 71b6d6e68ca19357a55bd3f59b61c00959f2f977 (plain)
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