JunkBox_Lib  1.10.2
xtools.c
Go to the documentation of this file.
1 
15 #include "xtools.h"
16 
17 
19 // Networks for IPv4 互換用
20 //
21 
38 int udp_recv_Buffer_sockaddr_in(int sock, Buffer* str, struct sockaddr_in* sv_addr)
39 {
40  int cc, cadlen;
41 
42  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
43 
44  cadlen = sizeof(*sv_addr);
45  memset(str->buf, 0, str->bufsz);
46  str->vldsz = 0;
47  str->state = JBXL_NORMAL;
48  cc = recvfrom(sock, (char*)str->buf, str->bufsz, 0, (struct sockaddr*)sv_addr, (socklen_t*)&cadlen);
49 
50  if (cc>=0) str->vldsz = cc;
51  else str->state = cc = JBXL_NET_RECV_ERROR;
52 
53  return cc;
54 }
55 
56 
72 int udp_send_Buffer_sockaddr_in(int sock, Buffer* str, struct sockaddr_in* sv_addr)
73 {
74  int cc;
75 
76  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
77 
78  if (str->vldsz<0) str->vldsz = (int)strlen((const char*)str->buf);
79  cc = sendto(sock, (char*)str->buf, str->vldsz, 0, (struct sockaddr*)sv_addr, sizeof(*sv_addr));
80 
81  if (cc<0) cc = JBXL_NET_SEND_ERROR;
82  return cc;
83 }
84 
85 
99 int udp_send_sBuffer_sockaddr_in(int sock, Buffer* str, struct sockaddr_in* sv_addr)
100 {
101  int cc;
102 
103  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
104 
105  cc = sendto(sock, (char*)str->buf, (int)strlen((const char*)str->buf), 0, (struct sockaddr*)sv_addr, sizeof(*sv_addr));
106  if (cc<0) cc = JBXL_NET_SEND_ERROR;
107 
108  return cc;
109 }
110 
111 
130 int udp_recv_Buffer_wait_sockaddr_in(int sock, Buffer* str, struct sockaddr_in* sv_addr, int tm)
131 {
132  int cc;
133 
134  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
135 
136  //memset(str->buf, 0, str->bufsz);
137  str->vldsz = 0;
138  cc = udp_recv_wait_sockaddr_in(sock, (char*)str->buf, str->bufsz, sv_addr, tm);
139  if (cc>=0) str->vldsz = cc;
140 
141  return cc;
142 }
143 
144 
156 struct sockaddr_in get_sockaddr_in_Buffer(Buffer buf)
157 {
158  int i, port = 0;
159  struct sockaddr_in addr;
160  memset(&addr, 0, sizeof(struct sockaddr_in));
161 
162  if (buf.buf==NULL) return addr;
163 
164  i = 0;
165  while (buf.buf[i]!='\0' && buf.buf[i]!=':') i++;
166  buf.buf[i] = '\0';
167 
168  port = atoi((char*)&buf.buf[i+1]);
169  addr = get_sockaddr_in((char*)buf.buf, port);
170 
171  return addr;
172 }
173 
174 
175 /*
176 Buffer get_hostport_sockaddr_in(struct sockaddr_in addr)
177 {
178  Buffer buf;
179  char hostport[LBUF];
180  char* ip = get_ipaddr_ipv4(addr.sin_addr);
181  unsigned short port = ntohs(addr.sin_port);
182 
183  snprintf(hostport, LBUF, "%s:%d", ip, port);
184 
185  buf = make_Buffer_bystr(hostport);
186  return buf;
187 }
188 */
189 
190 
191 
193 // Networks for IPv4/IPv6
194 //
195 
212 int udp_recv_Buffer(int sock, Buffer* str, struct addrinfo* sv_addr)
213 {
214  int cc;
215  socklen_t cadlen;
216 
217  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
218  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
219 
220  cadlen = (int)sv_addr->ai_addrlen;
221  memset(str->buf, 0, str->bufsz);
222  str->vldsz = 0;
223  str->state = JBXL_NORMAL;
224  cc = recvfrom(sock, (char*)str->buf, str->bufsz, 0, sv_addr->ai_addr, &cadlen);
225 
226  if (cc>=0) str->vldsz = cc;
227  else str->state = cc = JBXL_NET_RECV_ERROR;
228 
229  return cc;
230 }
231 
232 
248 int udp_send_Buffer(int sock, Buffer* str, struct addrinfo* sv_addr)
249 {
250  int cc;
251 
252  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
253  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
254 
255  if (str->vldsz<0) str->vldsz = (int)strlen((const char*)str->buf);
256  cc = sendto(sock, (char*)str->buf, str->vldsz, 0, sv_addr->ai_addr, (int)sv_addr->ai_addrlen);
257 
258  if (cc<0) cc = JBXL_NET_SEND_ERROR;
259 
260  return cc;
261 }
262 
263 
276 int tcp_recv_Buffer(int sock, Buffer* str)
277 {
278  int cc;
279 
280  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
281 
282  memset(str->buf, 0, str->bufsz);
283  str->vldsz = 0;
284  str->state = JBXL_NORMAL;
285  cc = recv(sock, (char*)str->buf, str->bufsz, 0);
286 
287  if (cc>=0) str->vldsz = cc;
288  else str->state = cc = JBXL_NET_RECV_ERROR;
289 
290  return cc;
291 }
292 
293 
305 int tcp_send_Buffer(int sock, Buffer* str)
306 {
307  int cc;
308 
309  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
310 
311  if (str->vldsz<0) str->vldsz = (int)strlen((const char*)str->buf);
312  cc = send(sock, (char*)str->buf, str->vldsz, 0);
313 
314  if (cc<0) cc = JBXL_NET_SEND_ERROR;
315  return cc;
316 }
317 
318 
337 int udp_recv_Buffer_wait(int sock, Buffer* str, struct addrinfo* sv_addr, int tm)
338 {
339  int cc;
340 
341  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
342  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
343 
344  //memset(str->buf, 0, str->bufsz);
345  str->vldsz = 0;
346  cc = udp_recv_wait(sock, (char*)str->buf, str->bufsz, sv_addr, tm);
347  if (cc>=0) str->vldsz = cc;
348 
349  return cc;
350 }
351 
352 
370 int tcp_recv_Buffer_wait(int sock, Buffer* str, int tm)
371 {
372  int cc;
373 
374  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
375 
376  //memset(str->buf, 0, str->bufsz);
377  str->vldsz = 0;
378  cc = tcp_recv_wait(sock, (char*)str->buf, str->bufsz, tm);
379  if (cc>=0) str->vldsz = cc;
380 
381  return cc;
382 }
383 
384 
400 int tcp_recv_Buffer_tosize(int sock, Buffer* str, Buffer* mod, int size)
401 {
402  int cc, sz;
403  int modon = FALSE;
404 
405  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
406  if (mod!=NULL && mod->buf!=NULL) modon = TRUE;
407 
408  if (modon) memset(mod->buf, 0, mod->vldsz);
410 
411  sz = str->vldsz;
412  while (sz<size) {
413  cc = tcp_recv_Buffer(sock, &buf);
414  if (cc>0) {
415  cat_Buffer(&buf, str);
416  sz += cc;
417  }
418  else {
419  if (cc<0) sz = cc;
420  break;
421  }
422  }
423  free_Buffer(&buf);
424 
425  if (sz>size && modon) {
426  copy_b2Buffer((void*)(str->buf+size), mod, sz-size);
427  str->vldsz = size;
428  }
429  return sz;
430 }
431 
432 
453 int tcp_recv_Buffer_tosize_wait(int sock, Buffer* str, Buffer* mod, int size, int tm)
454 {
455  int cc, sz;
456  int modon = FALSE;
457 
458  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
459  if (mod!=NULL && mod->buf!=NULL) modon = TRUE;
460 
461  if (modon) memset(mod->buf, 0, mod->vldsz);
463 
464  sz = str->vldsz;
465  while (sz<size) {
466  cc = tcp_recv_Buffer_wait(sock, &buf, tm);
467  if (cc>0) {
468  cat_Buffer(&buf, str);
469  sz += cc;
470  }
471  else {
472  if (cc<0) sz = cc;
473  break;
474  }
475  }
476  free_Buffer(&buf);
477 
478  if (sz>size && modon) {
479  copy_b2Buffer((void*)(str->buf+size), mod, sz-size);
480  str->vldsz = size;
481  }
482  return sz;
483 }
484 
485 
499 int udp_send_sBuffer(int sock, Buffer* str, struct addrinfo* sv_addr)
500 {
501  int cc;
502 
503  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
504  if (sv_addr==NULL) return JBXL_ARGS_ERROR;
505 
506  cc = sendto(sock, (char*)str->buf, (int)strlen((const char*)str->buf), 0, sv_addr->ai_addr, (int)sv_addr->ai_addrlen);
507  if (cc<0) cc = JBXL_NET_SEND_ERROR;
508 
509  return cc;
510 }
511 
512 
524 int tcp_send_sBuffer(int sock, Buffer* str)
525 {
526  int cc;
527 
528  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
529 
530  cc = send(sock, (char*)str->buf, (int)strlen((const char*)str->buf), 0);
531  return cc;
532 }
533 
534 
546 int tcp_send_sBufferln(int sock, Buffer* str)
547 {
548  int cc;
549  Buffer buf;
550 
551  if (str==NULL || str->buf==NULL) return JBXL_ARGS_ERROR;
552 
553  buf = dup_Buffer(*str);
554  cat_s2Buffer("\r\n", &buf);
555  cc = send(sock, (char*)buf.buf, (int)strlen((const char*)buf.buf), 0);
556  free_Buffer(&buf);
557 
558  return cc;
559 }
560 
561 
592 int tcp_recv_mstream_Buffer(int sock, Buffer* mesg, mstream* sb, int tm)
593 {
594  int cc;
595  unsigned char* pp;
596 
597  if (mesg==NULL || sb==NULL) return JBXL_ARGS_ERROR;
598  *mesg = make_Buffer(LBUF);
599 
600  if (sb->buf==NULL) {
601  *sb = make_mstream(RECVBUFSZ);
602  if (sb->buf==NULL) return JBXL_MALLOC_ERROR;
603  }
604 
605  while (sb->datano==0) {
606  cc = tcp_recv_Buffer_wait(sock, mesg, tm);
607  if (cc<=0) {
608  free_Buffer(mesg);
609  return cc;
610  }
611  put_mstream(sb, mesg->buf);
612  clear_Buffer(mesg);
613  }
614 
615  pp = get_mstream(sb);
616  if (pp==NULL) return JBXL_NET_BUF_ERROR;
617  copy_s2Buffer((char*)pp, mesg);
618  free(pp);
619 
620  return mesg->vldsz;
621 }
622 
623 
646 int tcp_recv_lines_Buffer(int sock, Buffer* mesg, int tm)
647 {
648  int cc;
649  Buffer buf;
650 
651  if (mesg==NULL) return JBXL_ARGS_ERROR;
652  buf = make_Buffer(LBUF);
653 
654  cc = tcp_recv_Buffer_wait(sock, &buf, tm);
655  while (cc>0) {
656  cat_Buffer(&buf, mesg);
657  if (buf.buf[cc-1]==CHAR_LF) break;
658  clear_Buffer(&buf);
659  cc = tcp_recv_Buffer_wait(sock, &buf, tm);
660  }
661  free_Buffer(&buf);
662 
663  if (cc<=0) {
664  free_Buffer(mesg);
665  return cc;
666  }
667 
668  return mesg->vldsz;
669 }
670 
671 
672 
674 // for URL
675 //
676 
687 Buffer comp_hostport(char* host, unsigned short port)
688 {
689  Buffer buf;
690  char hostport[LBUF];
691 
692  hostport[0] = '\0';
693 
694  if (host!=NULL) {
695  if (port!=0) snprintf(hostport, LBUF-1, "%s:%d", host, port);
696  else snprintf(hostport, LBUF-1, "%s", host);
697  }
698  else {
699  if (port!=0) snprintf(hostport, LBUF-1, "%d", port);
700  }
701 
702  buf = make_Buffer_bystr(hostport);
703 
704  return buf;
705 }
706 
707 
720 int decomp_hostport(Buffer buf, Buffer* host, unsigned short* port)
721 {
722  if (buf.buf==NULL) return FALSE;
723 
724  if (port!=NULL) {
725  int i = 0;
726  while (buf.buf[i]!='\0' && buf.buf[i]!=':') i++;
727  if (buf.buf[i]!='\0') *port = (unsigned short)atoi((char*)&buf.buf[i+1]);
728  else *port = 0;
729  }
730 
731  if (host!=NULL) {
732  Buffer hostport = dup_Buffer(buf);
733 
734  int i = 0;
735  while (hostport.buf[i]!='\0' && hostport.buf[i]!=':') i++;
736  hostport.buf[i] = '\0';
737  hostport.vldsz = (int)strlen((char*)hostport.buf);
738  *host = hostport;
739  }
740 
741  return TRUE;
742 }
743 
744 
757 Buffer comp_url(char* protocol, char* host, unsigned short port, char* dir)
758 {
759  Buffer url;
760  char num[20];
761 
762  url = make_Buffer(LNAME);
763 
764  if (protocol!=NULL) {
765  copy_s2Buffer(protocol, &url);
766  cat_s2Buffer("://", &url);
767  }
768 
769  cat_s2Buffer(host, &url);
770 
771  if (port!=0) {
772  snprintf(num, 10, ":%d", port);
773  cat_s2Buffer(num, &url);
774  }
775 
776  if (dir!=NULL) {
777  if (dir[0]!='/') cat_s2Buffer("/", &url);
778  cat_s2Buffer(dir, &url);
779  }
780 
781  return url;
782 }
783 
784 
807 int decomp_url(Buffer url, Buffer* srvurl, Buffer* protocol, Buffer* srvfqdn, unsigned short* sport, Buffer* srvdir)
808 {
809  Buffer item1, item2, item3, item4, wrk;
810 
811  if (srvurl !=NULL) *srvurl = init_Buffer();
812  if (protocol!=NULL) *protocol = init_Buffer();
813  if (srvfqdn !=NULL) *srvfqdn = init_Buffer();
814  if (srvdir !=NULL) *srvdir = init_Buffer();
815  if (sport !=NULL) *sport = 0;
816  if (url.buf ==NULL) return FALSE;
817 
818  item1 = init_Buffer();
819  item2 = init_Buffer();
820  item3 = init_Buffer();
821  item4 = init_Buffer();
822 
823  if (strstr((char*)url.buf, "://")!=NULL) {
824  // http(s)://www.tuis.ac.jp:8100/.....
825  item1 = awk_Buffer(url, '/', 1); // http(s):
826  item2 = awk_Buffer(url, '/', 3); // www.tuis.ac.jp:8100
827  if (protocol!=NULL) {
828  *protocol = dup_Buffer(item1);
829  protocol->buf[protocol->vldsz-1] = '\0';
830  protocol->vldsz--;
831  }
832  }
833  else {
834  // www.tuis.ac.jp:8100/.....
835  item2 = awk_Buffer(url, '/', 1); // www.tuis.ac.jp:8100
836  }
837 
838  if (item2.buf!=NULL) {
839  item3 = awk_Buffer(item2, ':', 1); // www.tuis.ac.jp
840  if (item3.buf==NULL) {
841  free_Buffer(&item1);
842  free_Buffer(&item2);
843  return FALSE;
844  }
845  item4 = awk_Buffer(item2, ':', 2); // 8100
846  }
847  else {
848  free_Buffer(&item1);
849  return FALSE;
850  }
851 
852  if (item4.buf!=NULL && sport!=NULL) {
853  *sport = (unsigned short)atoi((char*)item4.buf);
854  }
855 
856  wrk = make_Buffer(LBUF);
857  if (item1.buf!=NULL) {
858  copy_Buffer(&item1, &wrk);
859  cat_s2Buffer("//", &wrk);
860  }
861  cat_Buffer(&item2, &wrk);
862 
863  if (item3.buf!=NULL) {
864  if (srvfqdn!=NULL) *srvfqdn = item3;
865  else free_Buffer(&item3);
866  }
867 
868  if (srvdir!=NULL) {
869  *srvdir = make_Buffer_bystr((char*)(url.buf+strlen((char*)(wrk.buf))));
870  if ((srvdir->buf)[0]=='\0') copy_s2Buffer("/", srvdir);
871  }
872 
873  if (srvurl!=NULL) *srvurl = wrk;
874  else free_Buffer(&wrk);
875 
876  free_Buffer(&item1);
877  free_Buffer(&item2);
878  free_Buffer(&item4);
879 
880  return TRUE;
881 }
882 
883 
884 Buffer make_form_urlenc(const char* key, const char* val)
885 {
886  Buffer buf = init_Buffer();
887  if (key==NULL) return buf;
888 
889  buf = make_Buffer_str(key);
890  cat_s2Buffer("=", &buf);
891 
892  if (val!=NULL) {
893  unsigned char* val_enc = encode_urlenc((unsigned char*)val, -1);
894  if (val_enc!=NULL) {
895  cat_s2Buffer(val_enc, &buf);
896  free(val_enc);
897  }
898  }
899 
900  return buf;
901 }
902 
903 
904 void add_form_urlenc(Buffer* buf, const char* key, const char* val)
905 {
906  if (buf==NULL || key==NULL) return;
907 
908  cat_s2Buffer("&", buf);
909  cat_s2Buffer(key, buf);
910  cat_s2Buffer("=", buf);
911 
912  if (val!=NULL) {
913  unsigned char* val_enc = encode_urlenc((unsigned char*)val, -1);
914  if (val_enc!=NULL) {
915  cat_s2Buffer(val_enc, buf);
916  free(val_enc);
917  }
918  }
919 
920  return;
921 }
922 
923 
924 
926 // File I/O
927 //
928 
956 int save_tagged_Buffer(Buffer buf, FILE* fp, unsigned int mode, int prfm)
957 {
958  int cc;
959  Buffer tag, enc;
960 
961  tag = make_Buffer(2);
962  if (tag.buf==NULL) return FALSE;
963  tag.buf[0] = mode & 0x0f; // データの種別
964  tag.buf[1] = mode & 0xf0; // データの形式
965 
966  // JBXL_FIO_ORIGINAL, JBXL_FIO_BASE64 以外は未サポート
967  if (tag.buf[1]==JBXL_FIO_ORIGINAL || !prfm) {
968  enc = dup_Buffer(buf);
969  }
970  else if (tag.buf[1]==JBXL_FIO_BASE64) {
971  enc = encode_base64_Buffer(buf);
972  }
973  else {
974  enc = dup_Buffer(buf);
975  }
976 
977  tag.vldsz = 2;
978  cc = save_Buffer2_format_fp(tag, enc, fp);
979  free_Buffer(&enc);
980  free_Buffer(&tag);
981 
982  if (!cc) return FALSE;
983  return TRUE;
984 }
985 
986 
1013 Buffer read_tagged_Buffer(FILE* fp, unsigned int* mode)
1014 {
1015  unsigned char mthd, kind;
1016  Buffer tmp, tag, enc, buf;
1017 
1018  buf = init_Buffer();
1019  if (mode==NULL) return buf;
1020 
1021  if (!read_Buffer2_format_fp(&tag, &enc, fp)) return buf;
1022 
1023  kind = *mode & 0x0f; // データの種別
1024  mthd = *mode & 0xf0; // データの形式
1025  if (kind!=tag.buf[0] && kind!=JBXL_FIO_ANY) {
1026  free_Buffer(&enc);
1027  free_Buffer(&tag);
1028  return buf;
1029  }
1030 
1031  // JBXL_FIO_ORIGINAL, JBXL_FIO_BASE64 以外は未サポート
1032  if (mthd==tag.buf[1]) { // 保存形式と呼び出し形式は同じ
1033  buf = dup_Buffer(enc);
1034  }
1035  else {
1036  // 保存データをオリジナルへ
1037  if (tag.buf[1]==JBXL_FIO_BASE64) {
1038  tmp = decode_base64_Buffer(enc);
1039  }
1040  else {
1041  tmp = dup_Buffer(enc);
1042  }
1043 
1044  // オリジナルを呼び出し形式へ
1045  if (mthd==JBXL_FIO_BASE64) {
1046  buf = encode_base64_Buffer(tmp);
1047  }
1048  else {
1049  buf = dup_Buffer(tmp);
1050  }
1051  free_Buffer(&tmp);
1052  }
1053 
1054  *mode = (unsigned int)tag.buf[0]; // データ種別
1055  free_Buffer(&enc);
1056  free_Buffer(&tag);
1057 
1058  return buf;
1059 }
1060 
1061 
1081 {
1082  Buffer ret;
1083  unsigned char* pp;
1084 
1085  ret = init_Buffer();
1086 
1087  pp = fgets_mstream(buf.buf, sb);
1088  if (pp!=NULL) {
1089  ret = make_Buffer(LBUF);
1090  copy_s2Buffer((char*)pp, &ret);
1091  free(pp);
1092  }
1093  return ret;
1094 }
1095 
1096 
1097 
1099 // Run Length
1100 //
1101 
1116 int get_runlength_byte(unsigned char* buf, int len, int pos)
1117 {
1118  int i, sz;
1119 
1120  sz = -1;
1121  for (i=0; i<len; i++) {
1122  if (buf[i]==0x00) {
1123  if (i+1>=len) return JBXL_XTOOLS_RUNLEN_ERROR;
1124  if (buf[i+1]==0x00) return JBXL_XTOOLS_RUNLEN2_ERROR;
1125  sz += buf[i+1];
1126  if (sz>=pos) return i;
1127  i++;
1128  }
1129  else sz++;
1130 
1131  if (sz>=pos) return i;
1132  }
1133 
1134  return JBXL_ERROR;
1135 }
1136 
1137 
1149 Buffer decode_runlength(unsigned char* buf, int len, int sz)
1150 {
1151  int i, j, k;
1152  Buffer ret = init_Buffer();
1153 
1154  // 長さを数える
1155  i = j = 0;
1156  if (sz<=0) {
1157  while (j<len) {
1158  if (buf[j]==0x00) {
1159  if (j+1<len) {
1160  if (buf[j+1]==0x00) return ret;
1161  i += (int)buf[j+1];
1162  j += 2;
1163  }
1164  else break;
1165  }
1166  else {
1167  i++;
1168  j++;
1169  }
1170  }
1171 
1172  if (j==len) sz = i;
1173  else return ret;
1174  }
1175 
1176  ret = make_Buffer(sz);
1177  if (ret.buf==NULL) return ret;
1178 
1179  i = j = 0;
1180  while (i<sz && j<len) {
1181  if (buf[j]==0x00) {
1182  if (j+1<len) {
1183  for (k=0; k<(int)buf[j+1]; k++) ret.buf[i++] = 0x00;
1184  j += 2;
1185  }
1186  else break;
1187  }
1188  else ret.buf[i++] = buf[j++];
1189  }
1190 
1191  if (i==sz) ret.vldsz = sz;
1192  else free_Buffer(&ret);
1193 
1194  return ret;
1195 }
1196 
1197 
1198 Buffer encode_runlength(unsigned char* buf, int len)
1199 {
1200  int i, j, k;
1201  Buffer ret = init_Buffer();
1202 
1203  ret = make_Buffer(2*len);
1204  if (ret.buf==NULL) return ret;
1205 
1206  i = j = 0;
1207  while (j<len) {
1208  ret.buf[i] = buf[j];
1209 
1210  if (buf[j]==0x00) {
1211  k = 0;
1212  while (buf[j]==0x00 && j<len) {
1213  k++;
1214  j++;
1215  }
1216  ret.buf[i+1] = (unsigned char)k;
1217  i += 2;
1218  }
1219  else {
1220  i++;
1221  j++;
1222  }
1223  }
1224 
1225  ret.vldsz = i;
1226  return ret;
1227 }
1228 
1229 
1230 
1232 // Ring Buffer
1233 //
1234 
1250 {
1251  if (rb==NULL) return JBXL_ARGS_ERROR;
1252  rb->state = JBXL_NORMAL;
1253 
1254  if (buf==NULL) return JBXL_ARGS_ERROR;
1255  if (rb->buf==NULL) return JBXL_TOOLS_BUF_ERROR;
1256  if (rb->datasz + buf->vldsz > rb->bufsz) {
1257  rb->state = JBXL_ERROR;
1258  return JBXL_TOOLS_BUFSZ_ERROR;
1259  }
1260 
1261  if (rb->epoint + buf->vldsz <= rb->bufsz) {
1262  memcpy(&(rb->buf[rb->epoint]), buf->buf, buf->vldsz);
1263  rb->epoint = rb->epoint + buf->vldsz;
1264  if (rb->epoint==rb->bufsz) rb->epoint = 0;
1265  }
1266  else {
1267  memcpy(&(rb->buf[rb->epoint]), buf->buf, rb->bufsz - rb->epoint);
1268  memcpy(rb->buf, &(buf->buf[rb->bufsz - rb->epoint]), buf->vldsz - (rb->bufsz - rb->epoint));
1269  rb->epoint = rb->epoint + buf->vldsz - rb->bufsz;
1270  }
1271 
1272  rb->datasz += buf->vldsz;
1273  return buf->vldsz;
1274 }
1275 
1276 
1291 {
1292  if (rb==NULL) return NULL;
1293  if (rb->buf==NULL) return NULL;
1294  if (sz>rb->datasz) return NULL;
1295 
1296  Buffer* buf = new_Buffer(sz);
1297 
1298  if (rb->spoint + sz <= rb->bufsz) {
1299  copy_b2Buffer(&(rb->buf[rb->spoint]), buf, sz);
1300  rb->spoint = rb->spoint + sz;
1301  if (rb->spoint==rb->bufsz) rb->spoint = 0;
1302  }
1303  else {
1304  copy_b2Buffer(&(rb->buf[rb->spoint]), buf, rb->bufsz - rb->spoint);
1305  cat_b2Buffer(rb->buf, buf, sz - (rb->bufsz - rb->spoint));
1306  rb->spoint = rb->spoint + sz - rb->bufsz;
1307  }
1308 
1309  rb->datasz -= sz;
1310  return buf;
1311 }
1312 
1313 
1314 
1316 // Buffer 配列
1317 //
1318 
1331 {
1332  int nn, mx;
1333  tList* lt;
1334  Buffer* buf;
1335  Buffer* ret;
1336 
1337  if (lp==NULL) return NULL;
1338 
1339  // リスト中のノードの数を数える.
1340  lt = lp;
1341  nn = 0;
1342  while(lt!=NULL && lt->ldat.key.buf!=NULL) {
1343  nn++;
1344  lt = lt->next;
1345  }
1346  if (nn==0) return NULL;
1347 
1348  mx = nn;
1349  buf = ret = (Buffer*)malloc(sizeof(Buffer)*mx);
1350  if (ret==NULL) return NULL;
1351  memset(buf, 0, sizeof(Buffer)*mx);
1352 
1353  nn = 0;
1354  while(lp!=NULL && lp->ldat.key.buf!=NULL) {
1355  *buf = dup_Buffer(lp->ldat.key);
1356  buf->state = mx - nn;
1357  nn++;
1358  buf++;
1359  lp = lp->next;
1360  }
1361 
1362  return ret;
1363 }
1364 
1365 
1378 {
1379  int nn, mx;
1380  tList* lt;
1381  Buffer* buf;
1382  Buffer* ret;
1383 
1384  if (lp==NULL) return NULL;
1385 
1386  lt = lp;
1387  nn = 0;
1388  while(lt!=NULL && lt->ldat.val.buf!=NULL) {
1389  nn++;
1390  lt = lt->next;
1391  }
1392  if (nn==0) return NULL;
1393 
1394  mx = nn;
1395  buf = ret = (Buffer*)malloc(sizeof(Buffer)*mx);
1396  if (ret==NULL) return NULL;
1397  memset(buf, 0, sizeof(Buffer)*mx);
1398 
1399  nn = 0;
1400  while(lp!=NULL && lp->ldat.val.buf!=NULL) {
1401  *buf = dup_Buffer(lp->ldat.val);
1402  buf->state = mx - nn;
1403  nn++;
1404  buf++;
1405  lp = lp->next;
1406  }
1407 
1408  return ret;
1409 }
1410 
1411 
1427 {
1428  Buffer* bf = NULL;
1429 
1430  tList* lp = awk_Buffer_tList(buf, cc);
1431  if (lp!=NULL) bf = get_Buffer_dim_tList(lp);
1432  del_all_tList(&lp);
1433 
1434  return bf;
1435 }
1436 
1437 
1454 {
1455  Buffer* bf = NULL;
1456 
1457  tList* lp = cawk_Buffer_tList(buf, cc);
1458  if (lp!=NULL) bf = get_Buffer_dim_tList(lp);
1459  del_all_tList(&lp);
1460 
1461  return bf;
1462 }
1463 
1464 
1480 {
1481  Buffer* dim;
1482  int i, n, m;
1483 
1484  if (buf.buf==NULL) return NULL;
1485 
1486  n = i = 0;
1487  while(buf.buf[i]!='\0' && i<buf.vldsz) {
1488  if (buf.buf[i]==CHAR_CR) {
1489  n++;
1490  if (i+1<buf.vldsz && buf.buf[i+1]==CHAR_LF) i++;
1491  }
1492  else if (buf.buf[i]==CHAR_LF) n++;
1493  else if (i+1<buf.vldsz && buf.buf[i+1]=='\0') n++;
1494  else if (i+1==buf.vldsz || buf.buf[i+1]=='\0') n++;
1495  i++;
1496  }
1497  if (n==0) n = 1; // buf.buf[0]=='\0' の場合
1498 
1499  dim = (Buffer*)malloc(sizeof(Buffer)*n);
1500  if (dim==NULL) return NULL;
1501  memset(dim, 0, sizeof(Buffer)*n);
1502 
1503  int nxt = 0;
1504  for (m=0; m<n-1; m++) {
1505  int cnt = 0;
1506  int fwd = 0;
1507  while (buf.buf[nxt+cnt]!=CHAR_CR && buf.buf[nxt+cnt]!=CHAR_LF && nxt+cnt<buf.vldsz) cnt++;
1508 
1509  if (buf.buf[nxt+cnt]==CHAR_CR || buf.buf[nxt+cnt]==CHAR_LF) fwd++;
1510  if (buf.buf[nxt+cnt]==CHAR_CR && nxt+cnt+1<buf.vldsz && buf.buf[nxt+cnt+1]==CHAR_LF) fwd++;
1511  if (mode==ON) cnt += fwd;
1512 
1513  dim[m] = make_Buffer(cnt);
1514  for (i=0; i<cnt; i++) {
1515  dim[m].buf[i] = buf.buf[nxt+i];
1516  }
1517  dim[m].vldsz = cnt;
1518  dim[m].state = n;
1519 
1520  if (mode==ON) nxt += cnt;
1521  else nxt += cnt + fwd;
1522  }
1523 
1524  // m == n-1 一番最後の領域
1525  dim[n-1] = make_Buffer(buf.vldsz-nxt);
1526  for (i=0; i<buf.vldsz-nxt; i++) {
1527  dim[n-1].buf[i] = buf.buf[nxt+i];
1528  }
1529  dim[n-1].vldsz = buf.vldsz - nxt;
1530  dim[n-1].state = n;
1531 
1532  return dim;
1533 }
1534 
1535 
1541 Buffer join_Buffer_dim(Buffer* dim, const char* deli)
1542 {
1543  int i, nn;
1544  Buffer buf;
1545 
1546  buf = init_Buffer();
1547  if (dim==NULL) return buf;
1548 
1549  buf = make_Buffer(LBUF);
1550  nn = dim->state;
1551 
1552  for (i=0; i<nn; i++) {
1553  cat_Buffer(dim, &buf);
1554  if (deli!=NULL && i!=nn-1) cat_s2Buffer(deli, &buf);
1555  dim++;
1556  }
1557 
1558  return buf;
1559 }
1560 
1561 
1568 {
1569  int i, nn;
1570  Buffer* buf;
1571 
1572  if (dim==NULL || *dim==NULL) return;
1573  buf = *dim;
1574 
1575  nn = buf->state;
1576  if (nn<=0) free_Buffer(buf);
1577 
1578  for (i=0; i<nn; i++) {
1579  free_Buffer(buf);
1580  buf++;
1581  }
1582 
1583  free(*dim);
1584  *dim = NULL;
1585  return;
1586 }
1587 
1588 
1589 
1591 // リスト Buffer
1592 //
1593 
1604 {
1605  if (buf.buf==NULL || n<=0) return NULL;
1606 
1608  if (line.buf==NULL) return NULL;
1609 
1610  char* packline = pack_char((char*)line.buf, ' ');
1611  free_Buffer(&line);
1612  if (packline==NULL) return NULL;
1613 
1614  tList* list = awk_tList(packline, ' ');
1615  free(packline);
1616 
1617  return list;
1618 }
1619 
1620 
1629 {
1630  if (buf.buf==NULL || *ptr<0) return NULL;
1631  if (*ptr>=buf.vldsz) return NULL;
1632 
1634  if (line.buf==NULL) return NULL;
1635 
1636  char* packline = pack_char((char*)line.buf, ' ');
1637  free_Buffer(&line);
1638  if (packline==NULL) return NULL;
1639 
1640  tList* list = awk_tList(packline, ' ');
1641  free(packline);
1642 
1643  return list;
1644 }
1645 
1646 
1647 
1649 // Extend tList
1650 //
1651 
1668 int set_item_tList(tList* list, char* key, int no, char deli, int nm, char* value)
1669 {
1670  int cn = 0;
1671  tList* lp;
1672 
1673  if (list==NULL || key==NULL || value==NULL) return JBXL_ARGS_ERROR;
1674 
1675  if (no>0) {
1676  lp = strncasecmp_tList(list, key, 0, no);
1677  if (lp!=NULL) {
1678  int rep = set_item_tList_node(lp, deli, nm, value);
1679  if (rep) cn = 1;
1680  }
1681  }
1682  else { // no<=0
1683  int nn = 1;
1684  cn = 0;
1685  lp = strncasecmp_tList(list, key, 0, nn);
1686  while (lp!=NULL) {
1687  int rep = set_item_tList_node(lp, deli, nm, value);
1688  if (rep) cn++;
1689  lp = strncasecmp_tList(list, key, 0, ++nn);
1690  }
1691  }
1692 
1693  return cn;
1694 }
1695 
1696 
1697 int set_item_tList_node(tList* lp, char deli, int nm, char* value)
1698 {
1699  int rep = FALSE;
1700  char dl[2] = " ";
1701  Buffer* bp;
1702 
1703  if (lp==NULL || value==NULL) return FALSE;
1704 
1705  dl[0] = deli;
1706 
1707  bp = cawk_Buffer_dim(lp->ldat.val, deli);
1708  if (bp!=NULL && bp->state>=nm) {
1709  Buffer buf = make_Buffer_bystr(value);
1710  free_Buffer(&bp[nm-1]);
1711  bp[nm-1] = buf;
1712 
1713  free_Buffer(&lp->ldat.val);
1714  lp->ldat.val = join_Buffer_dim(bp, dl);
1715  rep = TRUE;
1716  }
1717  del_Buffer_dim(&bp);
1718 
1719  return rep;
1720 }
1721 
1722 
1740 int replace_item_tList(tList* list, char* key, int no, char deli, int nm, char* srcval, char* value)
1741 {
1742  int cn = 0;
1743  tList* lp;
1744 
1745  if (list==NULL || key==NULL || value==NULL) return JBXL_ARGS_ERROR;
1746  if (srcval==NULL) {
1747  return set_item_tList(list, key, no, deli, nm, value);
1748  }
1749 
1750  if (no>0) {
1751  lp = strncasecmp_tList(list, key, 0, no);
1752  if (lp!=NULL) {
1753  int rep = replace_item_tList_node(lp, deli, nm, srcval, value);
1754  if (rep) cn = 1;
1755  }
1756  }
1757  else { // no<=0
1758  int nn = 1;
1759  cn = 0;
1760  lp = strncasecmp_tList(list, key, 0, nn);
1761  while (lp!=NULL) {
1762  int rep = replace_item_tList_node(lp, deli, nm, srcval, value);
1763  if (rep) cn++;
1764  lp = strncasecmp_tList(list, key, 0, ++nn);
1765  }
1766  }
1767 
1768  return cn;
1769 }
1770 
1771 
1772 int replace_item_tList_node(tList* lp, char deli, int nm, char* srcval, char* value)
1773 {
1774  int rep = FALSE;
1775  char dl[2] = " ";
1776  Buffer* bp;
1777  Buffer buf;
1778 
1779  if (lp==NULL || value==NULL) return FALSE;
1780  if (nm<=0) nm = 1;
1781  if (srcval==NULL) {
1782  return set_item_tList_node(lp, deli, nm, value);
1783  }
1784 
1785  dl[0] = deli;
1786 
1787  bp = cawk_Buffer_dim(lp->ldat.val, deli);
1788  if (bp!=NULL && bp->state>=nm) {
1789  buf = replace_sBuffer(bp[nm-1], srcval, value);
1790  free_Buffer(&bp[nm-1]);
1791  bp[nm-1] = buf;
1792  free_Buffer(&lp->ldat.val);
1793  lp->ldat.val = join_Buffer_dim(bp, dl);
1794  rep = TRUE;
1795  }
1796  del_Buffer_dim(&bp);
1797 
1798  return rep;
1799 }
1800 
1801 
1802 
1804 // File/Directory Tools
1805 //
1806 
1818 tList* get_dir_files(const char* dirn)
1819 {
1820  tList* lp = NULL;
1821  tList* ln = NULL;
1822 
1823 #ifdef WIN32
1824 // WIN32_FIND_DATA FindFileData;
1825  WIN32_FIND_DATAA FindFileData;
1826  HANDLE hFind;
1827 
1828  Buffer pth = make_Buffer_bystr(dirn);
1829  if (pth.buf[strlen((char*)pth.buf)-1]!='\\') cat_s2Buffer("\\", &pth);
1830  Buffer buf = dup_Buffer(pth);
1831  cat_s2Buffer("*", &buf);
1832 
1833 // hFind = FindFirstFile((LPCTSTR)(buf.buf), &FindFileData);
1834  hFind = FindFirstFileA((LPCSTR)(buf.buf), &FindFileData);
1835  if (hFind!=INVALID_HANDLE_VALUE) {
1836  Buffer tmp;
1837  do {
1838  if (strcmp(".", FindFileData.cFileName) && strcmp("..", FindFileData.cFileName)) {
1839  int fkind = 0; // other file
1840  if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) fkind = 1; // directory
1841  tmp = dup_Buffer(pth);
1842  cat_s2Buffer(FindFileData.cFileName, &tmp);
1843  ln = add_tList_node_str(ln, NULL, tmp.buf);
1844  if (ln!=NULL) ln->ldat.lv = fkind;
1845  if (lp==NULL) lp = ln;
1846  free_Buffer(&tmp);
1847  }
1848  } while (FindNextFileA(hFind, &FindFileData));
1849 
1850  FindClose(hFind);
1851  }
1852  free_Buffer(&buf);
1853  free_Buffer(&pth);
1854 
1855 #else
1856 
1857  DIR *dp;
1858  struct dirent *dir;
1859 
1860  Buffer pth = make_Buffer_bystr(dirn);
1861  if (pth.buf[strlen((char*)pth.buf)-1]!='/') cat_s2Buffer("/", &pth);
1862 
1863  dp = opendir(dirn);
1864  if (dp!=NULL ){
1865  Buffer tmp;
1866  dir = readdir(dp);
1867  while (dir != NULL ){
1868  if (strcmp(".", dir->d_name) && strcmp("..", dir->d_name)) {
1869  int fkind = 0; // other file
1870  if (dir->d_type==DT_DIR) fkind = 1; // directory
1871  tmp = dup_Buffer(pth);
1872  cat_s2Buffer(dir->d_name, &tmp);
1873  ln = add_tList_node_str(ln, NULL, (char*)tmp.buf);
1874  if (ln!=NULL) ln->ldat.lv = fkind;
1875  if (lp==NULL) lp = ln;
1876  free_Buffer(&tmp);
1877  }
1878  dir = readdir(dp);
1879  }
1880 
1881  closedir(dp);
1882  }
1883  free_Buffer(&pth);
1884 
1885 #endif
1886 
1887  // sort
1888  ln = lp;
1889  while (ln!=NULL) {
1890  tList* lo = ln->next;
1891  while (lo!=NULL) {
1892  if (strcmp((char*)ln->ldat.val.buf, (char*)lo->ldat.val.buf)>0) {
1893  swap_tList_node(ln, lo);
1894  }
1895  lo = lo->next;
1896  }
1897  ln = ln->next;
1898  }
1899 
1900  return lp;
1901 }
1902 
1903 
1904 tList* get_dir_files_rcsv(const char* dirn)
1905 {
1906  tList* lp = get_dir_files(dirn);
1907  if (lp==NULL) return NULL;
1908 
1909  tList* lt = dup_tList(lp);
1910  while (lt!=NULL) {
1911  if (lt->ldat.lv==1) {
1912  tList* lc = get_dir_files_rcsv((char*)lt->ldat.val.buf);
1913  if (lc!=NULL) lp = add_tList_end(lc, lp);
1914  }
1915  lt = lt->next;
1916  }
1917  del_tList(&lt);
1918 
1919  return lp;
1920 }
1921 
1922 
1923 void rm_dir_rcsv(const char* dirn)
1924 {
1925  if (dirn==NULL) return;
1926 
1927  tList* lp = get_dir_files_rcsv(dirn);
1928  tList* lt = lp;
1929  while (lt!=NULL) {
1930  if (lt->ldat.lv==1) rmdir((char*)lt->ldat.val.buf);
1931  else unlink((char*)lt->ldat.val.buf);
1932  lt = lt->next;
1933  }
1934  rmdir(dirn);
1935  //
1936  del_tList(&lp);
1937  return;
1938 }
1939 
1940 
1942 {
1943  if (path==NULL) return;
1944 
1945  int count = path->vldsz - 1;
1946  while (count>=0) {
1947  if (path->buf[count]=='.') {
1948  path->buf[count] = '\0';
1949  path->vldsz = (int)strlen((char*)path->buf);
1950  break;
1951  }
1952  count--;
1953  }
1954 }
1955 
1956 
1960 void change_file_extension_Buffer(Buffer* path, const char* ext)
1961 {
1962  if (path==NULL) return;
1963 
1964  int count = path->vldsz - 1;
1965  while (count>=0) {
1966  if (path->buf[count]=='.') {
1967  path->buf[count] = '\0';
1968  path->vldsz = (int)strlen((char*)path->buf);
1969  if (ext[0]!='.') cat_s2Buffer(".", path);
1970  cat_s2Buffer(ext, path);
1971  break;
1972  }
1973  else if (path->buf[count]=='/' || path->buf[count]=='\\') {
1974  count = -1;
1975  break;
1976  }
1977  count--;
1978  }
1979  //
1980  if (count<0) {
1981  if (ext[0]!='.') cat_s2Buffer(".", path);
1982  cat_s2Buffer(ext, path);
1983  }
1984 }
1985 
1986 
1987 /*
1988 Buffer relative_path_Buffer(Buffer src, Buffer dst)
1989 
1990 src から dst への相対パスを返す.
1991 
1993 片方が絶対パスでもう片方が相対パスの場合,結果は不正確になる.
1994 */
1996 {
1997  Buffer rlt = init_Buffer();
1998  if (src.buf==NULL || dst.buf==NULL) return rlt;
1999  if (src.buf[0]=='\0') {
2000  rlt = dup_Buffer(dst);
2001  return rlt;
2002  }
2003 
2004  Buffer path_a = dup_Buffer(src);
2005  Buffer path_b = dup_Buffer(dst);
2006  // 区切り文字の追加
2007  if (path_a.buf[path_a.vldsz-1]!=CHAR_DELI_DIR) cat_s2Buffer(STR_DELI_DIR, &path_a);
2008  if (path_b.buf[path_b.vldsz-1]!=CHAR_DELI_DIR) cat_s2Buffer(STR_DELI_DIR, &path_b);
2009 
2010  int i = 0;
2011  char a = path_a.buf[0];
2012  char b = path_b.buf[0];
2013  while (a==b && a!='\0') {
2014  i++;
2015  a = path_a.buf[i];
2016  b = path_b.buf[i];
2017  } // i : pat_a と path_b の違っている箇所
2018  if (a==CHAR_DELI_DIR && i>0) a = path_a.buf[--i];
2019  //
2020  // 手前の区切り文字
2021  while (i>=0 && a!=CHAR_DELI_DIR) a = path_a.buf[--i];
2022  i++; // 区切り文字の次
2023 
2024  int n = 0, h = i;
2025  char c = path_a.buf[h];
2026  while(c!='\0') {
2027  if (c==CHAR_DELI_DIR) n++;
2028  c = path_a.buf[++h];
2029  }
2030  if (h!=i) n++;
2031 
2032  if (n==0) {
2034  }
2035  else {
2036  int j;
2037  for (j=0; j<n; j++) {
2038  cat_s2Buffer(STR_UPST_DIR, &rlt);
2039  }
2040  cat_s2Buffer(&path_b.buf[i], &rlt);
2041  }
2042 
2043  free_Buffer(&path_a);
2044  free_Buffer(&path_b);
2045 
2046  return rlt;
2047 }
2048 
2049 
2057 void canonical_filename_Buffer(Buffer* fname, int no_dir)
2058 {
2059  if (fname==NULL || fname->buf==NULL) return;
2060 
2061  rewrite_Buffer_bychar(fname, ' ', '_');
2062  rewrite_Buffer_bychar(fname, '!', '_');
2063  rewrite_Buffer_bychar(fname, '$', '_');
2064  rewrite_Buffer_bychar(fname, '&', '_');
2065  rewrite_Buffer_bychar(fname, '~', '_');
2066  rewrite_Buffer_bychar(fname, '|', '_');
2067  rewrite_Buffer_bychar(fname, ':', '_');
2068  rewrite_Buffer_bychar(fname, ';', '_');
2069  rewrite_Buffer_bychar(fname, '*', '_');
2070  rewrite_Buffer_bychar(fname, '?', '_');
2071  rewrite_Buffer_bychar(fname, '`', '_');
2072  rewrite_Buffer_bychar(fname, '"', '_');
2073  rewrite_Buffer_bychar(fname, '\'', '_');
2074  rewrite_Buffer_bychar(fname, '@', '_');
2075  rewrite_Buffer_bychar(fname, '[', '_');
2076  rewrite_Buffer_bychar(fname, ']', '_');
2077  rewrite_Buffer_bychar(fname, '(', '_');
2078  rewrite_Buffer_bychar(fname, ')', '_');
2079  rewrite_Buffer_bychar(fname, '<', '_');
2080  rewrite_Buffer_bychar(fname, '>', '_');
2081  if (no_dir) {
2082  rewrite_Buffer_bychar(fname, '/', '_');
2083  rewrite_Buffer_bychar(fname, '\\', '_');
2084  }
2085  return;
2086 }
2087 
2088 
2089 
2091 // ファイルリスト
2092 
2099 tList* _add_key_val_list(tList* pp, tList* list, const char* key, const char* val, int mode)
2100 {
2101  // 同一キーがあった場合の処理
2102  tList* fnd = strncasecmp_tList(list, key, 0, 1);
2103  if (fnd!=NULL) {
2104  if (mode==1) { // スキップ
2105  return pp;
2106  }
2107  else if (mode==2) { // 上書き
2108  if (pp==fnd) pp = fnd->prev;
2109  del_tList_node(&fnd);
2110  }
2111  }
2112  // データ追加
2113  tList_data ldat = make_tList_data_str(key, val);
2114  pp = add_tList_node_bydata(pp, ldat);
2115 
2116  return pp;
2117 }
2118 
2119 
2133 tList* add_resource_list(const char* path, int keylen, tList* list, tList* extn, int mode)
2134 {
2135  if (path==NULL) return list;
2136  if (list==NULL) list = new_tList_anchor_node();
2137 
2138  tList* pp = find_tList_end(list);
2139  tList* lp = get_dir_files(path);
2140  tList* tp = lp;
2141 
2142  // Generate Key. ファイル名の先頭 keylen文字をキーにする.
2143  while (lp!=NULL) {
2144  Buffer fn = make_Buffer_bystr(get_file_name((char*)lp->ldat.val.buf)); // ファイル名
2145  char* ext = get_file_extension((char*)fn.buf);
2146  //
2147  if (extn==NULL || strncasecmp_tList(extn, ext, 0, 1)==NULL) { // 拡張子の検査
2148  if (keylen<=0) {
2149  pp = _add_key_val_list(pp, list, (char*)fn.buf, (char*)lp->ldat.val.buf, mode);
2150  }
2151  else if (fn.vldsz>=keylen) {
2152  fn.buf[keylen] = '\0';
2153  fn.vldsz = keylen;
2154  pp = _add_key_val_list(pp, list, (char*)fn.buf, (char*)lp->ldat.val.buf, mode);
2155  }
2156  }
2157  if (list==NULL) list = pp;
2158  free_Buffer(&fn);
2159  lp = lp->next;
2160  }
2161 
2162  del_all_tList(&tp);
2163  return list;
2164 }
2165 
2166 
2176 char* get_resource_path(const char* name, tList* lp)
2177 {
2178  if (name==NULL) return NULL;
2179  if (lp==NULL) return NULL;
2180  if (lp->ldat.id==TLIST_ANCHOR_NODE) lp = lp->next;
2181 
2182  while (lp!=NULL) {
2183  if (!strcasecmp((char*)lp->ldat.key.buf, name)) {
2184  return (char*)lp->ldat.val.buf;
2185  }
2186  lp = lp->next;
2187  }
2188  return NULL;
2189 }
2190 
Buffer encode_base64_Buffer(Buffer buf)
バイナリデータ buf.bufの buf.vldszバイトを Base64にエンコード する
Definition: buffer.c:804
Buffer get_line_Buffer(Buffer str, int n)
複数行の文字列バッファから任意の行を取り出す.
Definition: buffer.c:956
Buffer make_Buffer(int sz)
Buffer型変数のバッファ部をつくり出す.
Definition: buffer.c:71
int read_Buffer2_format_fp(Buffer *key, Buffer *buf, FILE *fp)
ファイル fp から 2つのBuffer型変数の keyと bufを読み込む.
Definition: buffer.c:1819
int cat_b2Buffer(void *src, Buffer *dst, int len)
任意のバイナリデータsrcを Buffer型変数dstへ lenバイト catする.
Definition: buffer.c:585
void clear_Buffer(Buffer *str)
Buffer型変数 のバッファ部を 0クリアする.
Definition: buffer.c:272
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
void rewrite_Buffer_bychar(Buffer *buf, const char frm, const char toc)
buf.buf中の文字 frmを tocで置き換える
Definition: buffer.c:1703
Buffer dup_Buffer(Buffer buf)
Buffer型変数のコピーをつくる.
Definition: buffer.c:211
Buffer * new_Buffer(int sz)
空のBuffer型変数を生成する.
Definition: buffer.c:23
Buffer decode_base64_Buffer(Buffer str)
strのバッファを Base64からデコードする
Definition: buffer.c:850
int cat_Buffer(Buffer *src, Buffer *dst)
Buffer変数 srcから dstへバッファを catする.
Definition: buffer.c:384
int copy_Buffer(Buffer *src, Buffer *dst)
Buffer型変数 srcから dstへバッファをコピーする.
Definition: buffer.c:315
Buffer get_seq_data_Buffer(Buffer str, int *ptr)
複数行の文字列バッファ内の行データをシーケンシャルに取り出す.
Definition: buffer.c:1003
int save_Buffer2_format_fp(Buffer key, Buffer buf, FILE *fp)
ファイル fp へ 2つのBuffer型変数 keyと bufを書き込む
Definition: buffer.c:1733
int copy_b2Buffer(void *src, Buffer *dst, int len)
任意のバイナリデータsrcを Buffer型変数dstへ lenバイト copyする
Definition: buffer.c:518
Buffer awk_Buffer(Buffer str, char cc, int n)
Buffer文字列に対する awk.
Definition: buffer.c:1050
#define copy_s2Buffer(src, dst)
copy_b2Buffer()
Definition: buffer.h:108
#define make_Buffer_str(str)
set_Buffer()
Definition: buffer.h:61
#define replace_sBuffer(buf, f, t)
replace_sBuffer()
Definition: buffer.h:175
#define cat_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:122
#define make_Buffer_bystr(str)
set_Buffer()
Definition: buffer.h:57
#define LNAME
Definition: common.h:153
#define RECVBUFSZ
256K
Definition: common.h:134
#define LBUF
Definition: common.h:146
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
#define ON
Definition: common.h:230
void line(WSGraph vp, int x1, int y1, int x2, int y2, int cc)
Definition: graph.c:462
#define JBXL_ERROR
エラー
Definition: jbxl_state.h:34
#define JBXL_ARGS_ERROR
不正な引数(NULLなど)
Definition: jbxl_state.h:42
#define JBXL_TOOLS_BUFSZ_ERROR
バッファ(データ格納)部の大きさが足りない
Definition: jbxl_state.h:57
#define JBXL_XTOOLS_RUNLEN2_ERROR
Run Length データに 0x00, 0x00 が存在する(連長圧縮のデータではないのでは?)
Definition: jbxl_state.h:85
#define JBXL_NET_SEND_ERROR
データの送信エラー
Definition: jbxl_state.h:71
#define JBXL_NORMAL
正常
Definition: jbxl_state.h:32
#define JBXL_NET_RECV_ERROR
データの受信エラー
Definition: jbxl_state.h:70
#define JBXL_MALLOC_ERROR
メモリ確保エラー
Definition: jbxl_state.h:41
#define JBXL_NET_BUF_ERROR
受信バッファにデータは存在するはずだが,原因不明の理由により獲得に失敗した
Definition: jbxl_state.h:72
#define JBXL_XTOOLS_RUNLEN_ERROR
Run Length データが 0x00 で終わっている
Definition: jbxl_state.h:84
#define JBXL_TOOLS_BUF_ERROR
バッファ(データ格納)部の領域がない
Definition: jbxl_state.h:56
unsigned char ** buf
Definition: jpeg_tool.h:96
unsigned char unsigned long * len
Definition: jpeg_tool.h:96
int udp_recv_wait_sockaddr_in(int sock, char *rmsg, int size, struct sockaddr_in *sv_addr, int tm)
use udp_recv_wait()
Definition: network.c:2605
int tcp_recv_wait(int sock, char *mesg, int sz, int tm)
Definition: network.c:1317
struct sockaddr_in get_sockaddr_in(char *hostname, unsigned short cport)
Definition: network.c:2619
int udp_recv_wait(int sock, char *rmsg, int size, struct addrinfo *sv_addr, int tm)
Definition: network.c:1283
Definition: buffer.h:35
int bufsz
確保してあるバッファの大きさ - 1.
Definition: buffer.h:36
int vldsz
データの長さ.バイナリデータの場合も使用可能.文字列の場合は 0x00 を含まない.
Definition: buffer.h:37
int state
変数の状態を表す.正常は JBXL_NORMAL
Definition: buffer.h:38
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39
int bufsz
バッファ部のサイズ
Definition: tools.h:157
int datasz
保存されているデータの全体の長さ
Definition: tools.h:160
int state
リングバッファの状態
Definition: tools.h:163
unsigned char * buf
バッファ
Definition: tools.h:156
int spoint
バッファデータの開始点
Definition: tools.h:158
int epoint
バッファデータの終点+1 (データの追加点)
Definition: tools.h:159
tList * find_tList_end(tList *pl)
リストの最後のノードを探す.
Definition: tlist.c:1023
tList * cawk_Buffer_tList(Buffer buf, char cc)
Buffer 中の文字列を区切り文字で区切って,各項目をリストのキー部に入れて返す.連続文字列対応.
Definition: tlist.c:1914
tList * strncasecmp_tList(tList *pl, const char *key, int len, int no)
char* 型変数によるノードのサーチ.大文字小文字を無視する
Definition: tlist.c:1094
tList * new_tList_anchor_node(void)
リスト用の ANCHORノードを動的に生成.
Definition: tlist.c:371
tList * dup_tList(tList *pp)
リストを複製する.
Definition: tlist.c:843
void del_all_tList(tList **pp)
リストの全ノードの削除.ポインタ ppのノードを含むリスト全体を削除する.
Definition: tlist.c:769
tList * add_tList_end(tList *pp, tList *pt)
リストppの最後に リストptを追加する.
Definition: tlist.c:877
tList * awk_tList(char *str, char cc)
文字列を区切り文字で区切って,各項目をリストのキー部に入れて返す.
Definition: tlist.c:1805
tList * del_tList_node(tList **node)
リスト用のノードを削除.
Definition: tlist.c:270
tList * swap_tList_node(tList *pp1, tList *pp2)
pp1ノード と pp2ノードを入れ替える.
Definition: tlist.c:342
tList * awk_Buffer_tList(Buffer buf, char cc)
Buffer 中の文字列を区切り文字で区切って,各項目をリストのキー部に入れて返す.
Definition: tlist.c:1883
tList * del_tList(tList **pp)
指定したリストノード以降のリストを削除.
Definition: tlist.c:735
tList * add_tList_node_bydata(tList *pp, tList_data ldat)
データ(ldat)からリスト用ノードを生成し(new),それを指定したリストの後ろに追加.
Definition: tlist.c:417
#define make_tList_data_str(k, v)
make_tList_data_bystr()
Definition: tlist.h:111
#define add_tList_node_str(p, k, v)
add_tList_node_bystr()
Definition: tlist.h:142
#define TLIST_ANCHOR_NODE
アンカーノード
Definition: tlist.h:92
int put_mstream(mstream *sb, unsigned char *mesg)
メッセージ(文字列)ストリーム sb へメッセージ(の一部)を格納する
Definition: tools.c:3491
char * get_file_name(const char *str)
フルパスからファイル名へのポインタを取り出す.free() してはいけない.
Definition: tools.c:2066
unsigned char * get_mstream(mstream *sb)
メッセージ(文字列)ストリーム sb から次のメッセージを取り出す.改行コードは削除される.
Definition: tools.c:3532
char * get_file_extension(const char *str)
フルパスからファイル名の拡張子へのポインタを取り出す.free() してはいけない.
Definition: tools.c:2225
unsigned char * encode_urlenc(unsigned char *buf, int sz)
バイナリデータ bufを URLエンコードする.要 free()
Definition: tools.c:2980
unsigned char * fgets_mstream(unsigned char *mesg, mstream *sb)
メッセージストリームからメッセージを一行だけ取り出す.
Definition: tools.c:3592
#define mstream
バイト型 メッセージストリーム
Definition: tools.h:167
#define STR_CRNT_DIR
Definition: tools.h:104
#define make_mstream(s)
make_ringBuffer()
Definition: tools.h:385
#define CHAR_CR
改行
Definition: tools.h:78
#define CHAR_LF
ラインフィード
Definition: tools.h:79
#define CHAR_DELI_DIR
Definition: tools.h:102
#define STR_UPST_DIR
Definition: tools.h:105
#define STR_DELI_DIR
Definition: tools.h:103
#define pack_char(s, c)
pack_char_len()
Definition: tools.h:236
tList * get_dir_files(const char *dirn)
指定されたディレクトリにあるファイル名の一覧を取得.
Definition: xtools.c:1818
int tcp_send_sBuffer(int sock, Buffer *str)
TCP経由で文字列データを送信する.
Definition: xtools.c:524
Buffer decode_runlength(unsigned char *buf, int len, int sz)
0の連長圧縮された bufから szバイトの通常のデータを取り出す.
Definition: xtools.c:1149
Buffer * cawk_Buffer_dim(Buffer buf, char cc)
文字列を cawkで分解して配列を作る
Definition: xtools.c:1453
int tcp_send_sBufferln(int sock, Buffer *str)
TCPメッセージ(文字列)に改行(0x0d, 0x0a)を付け加えて送信する.
Definition: xtools.c:546
int udp_recv_Buffer(int sock, Buffer *str, struct addrinfo *sv_addr)
recvform()をラッピングした関数.UDPデータを受信する.
Definition: xtools.c:212
int replace_item_tList(tList *list, char *key, int no, char deli, int nm, char *srcval, char *value)
key をキーにした no番目のノードに対して replace_item_tList_node() を行う.
Definition: xtools.c:1740
Buffer comp_url(char *protocol, char *host, unsigned short port, char *dir)
"プロトコル://ホスト名:ポート番号/ディレクトリ名" の文字列を生成する.
Definition: xtools.c:757
tList * get_tList_line_Buffer(Buffer buf, int n)
buf から n行目を取り出して,' ' で分解してリストに格納して返す.
Definition: xtools.c:1603
int save_tagged_Buffer(Buffer buf, FILE *fp, unsigned int mode, int prfm)
Bufferを指定された形式に従ってタグ付きでファイルに保存する.
Definition: xtools.c:956
Buffer * decompline_Buffer_dim(Buffer buf, int mode)
データを行単位に分解する.改行は \r\n
Definition: xtools.c:1479
int tcp_recv_mstream_Buffer(int sock, Buffer *mesg, mstream *sb, int tm)
TCP経由でメッセージを受信する.バッファリングあり.
Definition: xtools.c:592
void canonical_filename_Buffer(Buffer *fname, int no_dir)
fname の問題になりそうな ASCII文字を '_' に変換する.
Definition: xtools.c:2057
Buffer encode_runlength(unsigned char *buf, int len)
bufの szバイトを 0で連長圧縮する
Definition: xtools.c:1198
Buffer relative_path_Buffer(Buffer src, Buffer dst)
path_a から path_b への相対パスを返す.
Definition: xtools.c:1995
tList * add_resource_list(const char *path, int keylen, tList *list, tList *extn, int mode)
ディレクトリ pathを検索して,リソースリストにファイルを追加し,リストの先頭を返す.
Definition: xtools.c:2133
void rm_dir_rcsv(const char *dirn)
指定されたディレクトリを再帰的に削除する.
Definition: xtools.c:1923
int tcp_send_Buffer(int sock, Buffer *str)
TCP経由でデータを送信する.
Definition: xtools.c:305
struct sockaddr_in get_sockaddr_in_Buffer(Buffer buf)
FQDN:port または IPaddress:port の形式の Buffer変数から ソケット情報を得る.IPv4専用
Definition: xtools.c:156
tList * get_tList_seq_data_Buffer(Buffer buf, int *ptr)
buf から行データをシーケンシャルに取り出して,それぞれを ' ' で分解してリストに格納して返す.
Definition: xtools.c:1628
int tcp_recv_Buffer_tosize_wait(int sock, Buffer *str, Buffer *mod, int size, int tm)
TCP経由でデータを size バイトまで受信する.待ち時間を指定できる.
Definition: xtools.c:453
int put_Buffer_ringBuffer(ringBuffer *rb, Buffer *buf)
リングバッファ rb へ Buffer データを vldszバイト格納する.
Definition: xtools.c:1249
int tcp_recv_Buffer(int sock, Buffer *str)
TCP経由でデータを受信する.バッファリングなし.
Definition: xtools.c:276
int udp_send_Buffer_sockaddr_in(int sock, Buffer *str, struct sockaddr_in *sv_addr)
sendto() をラッピングした関数.UDP経由でデータを送る.IPv4専用.
Definition: xtools.c:72
int udp_send_sBuffer(int sock, Buffer *str, struct addrinfo *sv_addr)
UDP経由で文字列データを送る.
Definition: xtools.c:499
int tcp_recv_lines_Buffer(int sock, Buffer *mesg, int tm)
TCP経由でメッセージを複数行受信する.簡易バッファリングあり.
Definition: xtools.c:646
int udp_recv_Buffer_sockaddr_in(int sock, Buffer *str, struct sockaddr_in *sv_addr)
recvform()をラッピングした関数.UDPデータを受信する.IPv4専用.
Definition: xtools.c:38
void change_file_extension_Buffer(Buffer *path, const char *ext)
ファイルの拡張子を extにする.ファイルに拡張子が無い場合は extを付加する
Definition: xtools.c:1960
Buffer * get_Buffer_dim_tList_value(tList *lp)
リストを分解してバリュー部(val)の配列を造る
Definition: xtools.c:1377
tList * get_dir_files_rcsv(const char *dirn)
指定されたディレクトリにあるファイル名の一覧を再帰的に取得.
Definition: xtools.c:1904
char * get_resource_path(const char *name, tList *lp)
リソースの名前から,ファイルのパスを得る.戻り値は free() してはいけない.
Definition: xtools.c:2176
int udp_recv_Buffer_wait_sockaddr_in(int sock, Buffer *str, struct sockaddr_in *sv_addr, int tm)
UDP経由でデータを受信する.IPv4専用.
Definition: xtools.c:130
void add_form_urlenc(Buffer *buf, const char *key, const char *val)
既存の文字に &key=val (valはURL Encodeされる) を追加する.
Definition: xtools.c:904
Buffer * get_Buffer_ringBuffer(ringBuffer *rb, int sz)
リングバッファ rb から szバイトのデータを取り出し,Buffer型データに格納する.要 del_Buffer()
Definition: xtools.c:1290
int tcp_recv_Buffer_tosize(int sock, Buffer *str, Buffer *mod, int size)
TCP経由でデータを size バイトまで受信する.バッファリングなし.
Definition: xtools.c:400
void del_Buffer_dim(Buffer **dim)
配列を削除する.
Definition: xtools.c:1567
Buffer comp_hostport(char *host, unsigned short port)
ホスト名とポート番号から,"ホスト名:ポート番号" の文字列を生成する.
Definition: xtools.c:687
Buffer read_tagged_Buffer(FILE *fp, unsigned int *mode)
save_tagged_Buffer() で保存したファイルから,Buffer をタグに従って読み込む.
Definition: xtools.c:1013
Buffer fgets_mstream_Buffer(Buffer buf, mstream *sb)
メッセージ buf.buf はメッセージストリームに一旦バッファリングされ,この関数により一行ずつ読み出される.
Definition: xtools.c:1080
Buffer make_form_urlenc(const char *key, const char *val)
key=val (valはURL Encodeされる)の文字を作成する.
Definition: xtools.c:884
int udp_send_Buffer(int sock, Buffer *str, struct addrinfo *sv_addr)
sendto() をラッピングした関数.UDP経由でデータを送る.
Definition: xtools.c:248
int replace_item_tList_node(tList *lp, char deli, int nm, char *srcval, char *value)
deliを区切りにした nm番目の項目(文字列)の srcval部分を valueで置き換える.
Definition: xtools.c:1772
Buffer join_Buffer_dim(Buffer *dim, const char *deli)
配列の要素を dliを間に入れて繋げる
Definition: xtools.c:1541
tList * _add_key_val_list(tList *pp, tList *list, const char *key, const char *val, int mode)
Definition: xtools.c:2099
int udp_recv_Buffer_wait(int sock, Buffer *str, struct addrinfo *sv_addr, int tm)
UDP経由でデータを受信する.待ち時間(タイムアウト)を指定できる.
Definition: xtools.c:337
int set_item_tList_node(tList *lp, char deli, int nm, char *value)
deliを区切りにした nm番目の項目(文字列)に value を設定する
Definition: xtools.c:1697
int decomp_url(Buffer url, Buffer *srvurl, Buffer *protocol, Buffer *srvfqdn, unsigned short *sport, Buffer *srvdir)
URLを分解する.
Definition: xtools.c:807
void del_file_extension_Buffer(Buffer *path)
ファイルの拡張子を削除する.
Definition: xtools.c:1941
int tcp_recv_Buffer_wait(int sock, Buffer *str, int tm)
TCP経由でデータを受信する.待ち時間(タイムアウト)を指定できる.
Definition: xtools.c:370
Buffer * awk_Buffer_dim(Buffer buf, char cc)
文字列を awkで分解して配列を作る
Definition: xtools.c:1426
int decomp_hostport(Buffer buf, Buffer *host, unsigned short *port)
"ホスト名:ポート番号" 形式の文字列から,ホスト名とポート番号を分離する.
Definition: xtools.c:720
int get_runlength_byte(unsigned char *buf, int len, int pos)
圧縮されていない状態で pos(Byte)の位置が,0の連長圧縮されているデータではどの位置に来るかを計算する
Definition: xtools.c:1116
int udp_send_sBuffer_sockaddr_in(int sock, Buffer *str, struct sockaddr_in *sv_addr)
DP経由で文字列データを送る.IPv4専用
Definition: xtools.c:99
int set_item_tList(tList *list, char *key, int no, char deli, int nm, char *value)
key をキーにした no番目のノードに対して set_item_tList_node() を行う.
Definition: xtools.c:1668
Buffer * get_Buffer_dim_tList(tList *lp)
リストを分解してキー部(key)の配列を造る
Definition: xtools.c:1330
汎用拡張ツールヘッダ
#define JBXL_FIO_ORIGINAL
Definition: xtools.h:27
#define JBXL_FIO_ANY
Definition: xtools.h:21
#define JBXL_FIO_BASE64
Definition: xtools.h:30