The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#ifndef UNICODE__JAPANESE__STR_H__
#define UNICODE__JAPANESE__STR_H__

/* $Id: str.h 4654 2006-07-03 01:33:16Z hio $ */

#ifndef UJ_UINT32
#define UJ_UINT32 unsigned int
#endif
#ifndef UJ_UINT16
#define UJ_UINT16 unsigned short
#endif
#ifndef UJ_UINT8
#define UJ_UINT8 unsigned char
#endif

/* ----------------------------------------------------------------------------
 * struct SV_Buf
 */
struct SV_Buf
{
  SV* sv;
  STRLEN alloc_len;
  UJ_UINT8* dst;
  UJ_UINT8* dst_begin;
  char tmpbuf[32];
};
typedef struct SV_Buf SV_Buf;

/* ----------------------------------------------------------------------------
 * SV_Buf(STRLEN len) */
#define SV_Buf_init(pbuf,len) \
  { \
    STRLEN alen; \
    (pbuf)->alloc_len = (len); \
    (pbuf)->sv = newSVpvn("",0); \
    alen = (len)+1; \
    SvGROW((pbuf)->sv,alen); \
    (pbuf)->dst_begin = (UJ_UINT8*)SvPV((pbuf)->sv,alen); \
    (pbuf)->dst = (pbuf)->dst_begin; \
  }

/* ----------------------------------------------------------------------------
 * STRLEN getLength(){ return dst-dst_begin; } */
#define SV_Buf_getLength(pbuf) ((pbuf)->dst-(pbuf)->dst_begin)
  
/* ----------------------------------------------------------------------------
 * void setLength(){ SvCUR_set(sv,dst-dst_begin); } */
#define SV_Buf_setLength(pbuf) SvCUR_set((pbuf)->sv,SV_Buf_getLength(pbuf))

/* ----------------------------------------------------------------------------
 * UJ_UINT8* getBegin(){ return dst_begin; } */
#define SV_Buf_getBegin(pbuf) ((pbuf)->dst_begin)

/* ----------------------------------------------------------------------------
 * SV* getSv() */
#define SV_Buf_getSv(pbuf) (*(pbuf)->dst='\0', (pbuf)->sv)

/* ----------------------------------------------------------------------------
 * inline void append_ch(UJ_UINT8 ch) */
#define SV_Buf_append_ch(pbuf,ch) \
  { \
    SV_Buf_checkbuf(pbuf,1); \
    *(pbuf)->dst++ = (ch); \
  }
/* ----------------------------------------------------------------------------
 * inline void append_ch2(UJ_UINT16 ch) */
#define SV_Buf_append_ch2(pbuf,ch) \
  { \
    const UJ_UINT16 xxtmp = (ch); \
    SV_Buf_checkbuf(pbuf,2); \
    memcpy((pbuf)->dst,&xxtmp,2); \
    (pbuf)->dst += 2; \
  } \
/* ----------------------------------------------------------------------------
 * inline void append_ch3(int ch) */
#define SV_Buf_append_ch3(pbuf,ch) \
  { \
    const int xxtmp = (ch); \
    SV_Buf_checkbuf(pbuf,4); \
    memcpy((pbuf)->dst,&xxtmp,3); \
    (pbuf)->dst += 3; \
  }
/* ----------------------------------------------------------------------------
 * inline void append_ch4(int ch) */
#define SV_Buf_append_ch4(pbuf,ch) \
  { \
    const int xxtmp = (ch); \
    SV_Buf_checkbuf(pbuf,4); \
    memcpy((pbuf)->dst,&xxtmp,4); \
    (pbuf)->dst += 4; \
  }
/* ----------------------------------------------------------------------------
 * inline void append_ch5(const UJ_UINT8* src) */
#define SV_Buf_append_ch5(pbuf,str) \
  { \
    SV_Buf_checkbuf(pbuf,5); \
    memcpy((pbuf)->dst,str,5); \
    (pbuf)->dst += 5; \
  }
/* ----------------------------------------------------------------------------
 * inline void append(const UJ_UINT8* src, int len) */
#define SV_Buf_append_mem(pbuf,str,len) \
  { \
    SV_Buf_checkbuf(pbuf,len); \
    memcpy((pbuf)->dst,str,len); \
    (pbuf)->dst += (len); \
  }

/* ----------------------------------------------------------------------------
 * inline void append_entityref(UJ_UINT32 ucs) */
#define SV_Buf_append_entityref(pbuf,ucs) \
  { \
    register int write_len = snprintf((pbuf)->tmpbuf,32,"&#%u;",ucs); \
    if( write_len!=-1 && write_len<32 ) \
    { \
      SV_Buf_append_mem(pbuf,(UJ_UINT8*)(pbuf)->tmpbuf,write_len); \
    }else \
    { \
      SV_Buf_append_ch(pbuf,'?'); \
    } \
  }

/* ----------------------------------------------------------------------------
 * void checkbuf(STRLEN len) */
#define SV_Buf_checkbuf(pbuf,len) \
  { \
    if( (STRLEN)((pbuf)->dst-(pbuf)->dst_begin)+(len)+1<(pbuf)->alloc_len ) \
    { \
    }else \
    { \
      STRLEN now_len; \
      STRLEN new_len; \
      STRLEN alen; \
      STRLEN curlen; \
      \
      SV_Buf_setLength(pbuf); \
      now_len = (pbuf)->dst-(pbuf)->dst_begin; \
      new_len = ((pbuf)->alloc_len+(len))*2; \
      alen = new_len+1; \
      SvGROW((pbuf)->sv,alen); \
      (pbuf)->alloc_len = new_len; \
       \
      (pbuf)->dst_begin = (UJ_UINT8*)SvPV((pbuf)->sv,curlen); \
      (pbuf)->dst = (pbuf)->dst_begin + now_len; \
    } \
  }


#endif