/* vi: set tabstop=4 nocindent noautoindent: */

#ifndef  __JBXL_BUFFER_H_
#define  __JBXL_BUFFER_H_


/**
	Buffer型サポートヘッダ  buffer.h

  	依存関係
	  	#include "common.h"
	  	#include "tools.h"
 */


#include "tools.h"






/**
Buffer型

  Buffer型は文字列操作時の配列破壊を防止する．buffer.c のBuffer型対応
  関数を使う限り, プログラマ(ライブラリ利用者)は配列破壊を考慮する必要は無い．
  通常, vldszはプログラマ(ライブラリ利用者)が保証しなければならない．
  したがってBuffer型変数を返す関数では常に vldszが設定されているか注意すべきである．
  ただし,データが文字列の場合は -1以下にしておいてもよい．
  一方 bufszはバッファの長さを現す変数であり，プログラマが書き換えてはいけない．

  Buffer型変数はバッファ領域を動的に確保するので,使用が終ったら必ず
  del_Buffer(または free_Buffer)でバッファ領域を開放しなければならない．

  注：buf[bufsz]はシステムが使用するので,プログラマは buf[bufsz]は無い
	  ものとして扱うこと．
  
  メンバ変数
	int   bufsz		 確保してあるバッファの大きさ - 1．
	int   vldsz		 バイナリデータを扱う場合,データの有効長をしめす．
	int   state		 変数の状態を表す．
	unsigned char* buf  バッファの先頭へのポインタ．str[bufsz]は必ず 0x00となる．
*/

typedef struct _Buffer {
	int   bufsz;
	int   vldsz;
	int   state;
	unsigned char* buf;
} Buffer;




// Buffer 変数の領域確保のための領域確保倍率
#define  BUFFER_FACT   (1.5)





/**/
Buffer* new_Buffer(void);
Buffer  init_Buffer(void);
Buffer  make_Buffer(int sz);
Buffer  make_Buffer_bychar(unsigned char cc);
Buffer  set_Buffer(void* buf, int sz);
Buffer  dup_Buffer(Buffer str);
Buffer  rept_Buffer(unsigned char cc, int n);

void	del_Buffer(Buffer** buf);
void	free_Buffer(Buffer* buf);
void	clear_Buffer(Buffer* buf);

#define make_Buffer_bybin(s, l)	set_Buffer((void*)(s), (l))
#define make_Buffer_bin(s, l)	set_Buffer((void*)(s), (l))
#define make_Buffer_bystr(s)	set_Buffer((void*)(s), -1)
#define make_Buffer_str(s)		set_Buffer((void*)(s), -1)
#define make_Buffer_char(s)  	make_Buffer_bychar(s)

int		copy_Buffer(Buffer* src, Buffer* dst);
int		cat_Buffer (Buffer* src, Buffer* dst);

int		copy_b2Buffer(void* src, Buffer* dst, int sz);
int		cat_b2Buffer (void* src, Buffer* dst, int sz);
int		copy_i2Buffer(int src, Buffer* dst);
int		cat_i2Buffer (int src, Buffer* dst);

#define copy_s2Buffer(s, d) 	copy_b2Buffer((void*)(s), (d), (int)strlen((const char*)(s)))
#define cat_s2Buffer(s, d) 	 	cat_b2Buffer( (void*)(s), (d), (int)strlen((const char*)(s)))



// ツール
void	kanji_convert_Buffer(Buffer* mesg);
Buffer  encode_base64_Buffer(Buffer buf);
Buffer  decode_base64_Buffer(Buffer buf);

Buffer  get_line_Buffer(Buffer buf, int n);  
Buffer  awk_Buffer (Buffer buf, char cc, int n);
Buffer  cawk_Buffer(Buffer buf, char cc, int n);

int	 	cmp_Buffer(Buffer src, Buffer dst, int n);
void	chomp_Buffer(Buffer* buf);
int		isText_Buffer(Buffer buf);
Buffer	dump_Buffer(Buffer buf);
int		recalc_strlen_Buffer(Buffer* buf);

//#define strlen_Buffer(b) 			strlen((char*)((b).buf))
#define strcmp_Buffer(a, b)			cmp_Buffer((a), (b), 0)
#define strncmp_Buffer(a, b, n)		cmp_Buffer((a), (b), (n))
#define bincmp_Buffer(a, b)			cmp_Buffer((a), (b), 0)
#define binncmp_Buffer(a, b, n)		cmp_Buffer((a), (b), (n))

Buffer  randstr_Buffer(int n);			   // 英数字を n個生成 
Buffer  randbit_Buffer(int n);			   // ビットを n個生成 


// ファイルI/O
int	 	fgets_Buffer(Buffer* str, FILE* fp);	// 拡張fgets
int		read_lines_Buffer(Buffer* str, FILE* fp);

Buffer  read_Buffer_file(char* fn);
Buffer  read_Buffer_data(FILE* fp, int sz);
int	 	save_Buffer_file(Buffer buf, char* fn);


// 文字削除
Buffer  erase_bBuffer(Buffer buf, char* bin, int len);
#define erase_Buffer(b, f)			erase_bBuffer((b), (char*)((f).buf), (f).vldsz))
#define erase_sBuffer(b, f)			erase_bBuffer((b), (char*)(f), strlen(f))


// 文字列置換
Buffer  replace_sBuffer_bystr(Buffer buf, char* frm, char* tos);
int	 	replace_sBuffer_file(char* fn, Buffer frm, Buffer tos);
#define replace_sBuffer(b, f, t)	replace_sBuffer_bystr((b), (f), (t))
#define replace_Buffer(b, f, t)		replace_sBuffer_bystr((b), (char*)((f).buf), (char*)((t).buf))



// ヘッダ(書式)付き特殊ファイルI/O
int	 	save_Buffer_fp(Buffer, FILE*);
Buffer  read_Buffer_fp(FILE*);
int   	save_Buffer2_fp(Buffer  key, Buffer  buf, FILE* fp);
int  	read_Buffer2_fp(Buffer* key, Buffer* buf, FILE* fp);




/**/
char*   dup_string(char* str);
#define dup_str(s)  dup_string((s))



#endif




