〜 ネットワーク 〜
クッキーを設定 (要WININET.DLL)

Windows標準搭載のWinInet.DLLのインターネットアクセス機能を用いて、
インターネットエクスプローラがハードディスクに保存するものと同じクッキーデータを保存します。
API関数InternetSetCookieで指定URLのCookieを保存するわけですが、
設定引数「URL」「キー」「データ」のうち、データ引数に有効期限情報も含めない場合は、
メモリに一時的に保存されるだけなので、セッションが終了するとクッキー情報も消滅するので、
ハードディスクに保存させる場合はデータ引数「値; expires = 有効期限情報」とエクスパイアしましょう。
有効期限の書式はRFC822で行うのでコチラのモジュールを併用しています。
ただ、そのままでは世界標準時(GMT)の日時ですので、パソコンのタイムゾーンに直す必要がありますが、
面倒なのでサンプルモジュールでは内部で設定タイムゾーンに関わらず日本(+9)時間を指定しています。
キー引数を指定せず(=0)、データ引数に「キー = 値」形式でも正常に保存出来ますし、
有効期限の指定に厳密な時間まで入れるとなると、モジュールに渡すパラメータ数が増えてしまうので、
何日後にするか日数のみを指定するようにしました。時間は翌朝の0時0分0秒です。
当然、指定日数後が何年何月何日になるかを計算する必要あるのでコチラのモジュールも併用していますし、
RFC822形式で必要な曜日も求める必要があるので、コチラのロジックをモジュール内で使用してます。
下記のHSP3側モジュールでは、API関数InternetSetCookieの引数同様に3つする形式ですが、
HSP3側のモジュールでは、第1・2パラメータの2つにしか設定できない文字列パラメータの制約により、
前述のデータ項目に「キー = 値」を格納して渡す形式を採用しています。
システム変数statに正常に設定できた(=1)か否(=0)かを返すようにしていますが、
実際に保存されたクッキーを確認したい場合、いつもクッキーが保存されるフォルダを直接確認しに行くか、
コチラのクッキー取得モジュールで取得してみると良いでしょう。
	

dateinit 基準年, 基準月, 基準日
基準年日付計算用の基準とする年を指定する。
基準月日付計算用の基準とする月を指定する。
基準日日付計算用の基準とする日を指定する。

adddays 受取先配列, 日数
受取先配列基準日から指定日数分を加減した日付の受取先配列を指定する。
要素0には演算後の年、要素1には演算後の月、要素2には演算後の日がセットされる。
日数加算または減算する日数を指定する。

setcookie URL, 保存内容, 期限
URL対象URLを指定する。
尚、内部でdateinit命令とadddays命令を使用しているため、
setcookie命令より前にdateinit命令とadddays命令を定義すること。
保存内容保存するキーとデータをイコールで挟んだ「キー=データ」形式で指定する。
期限ファイル保存しないセッションデータの場合を除き、有効期限日数を指定する。

dateformat 書式文字列, 日時配列, オプション
書式文字列変換したい書式を指定する。
%yは年、%moは月、%wは曜、%dは日、%hは時、%miは分、%sは秒、%msはミリ秒に変換される。
尚、書式付日時文字列はrefstrに代入される。
日時配列変換元の数値を入れた配列変数(0:年 1:月 2:曜 3:日 4:時 5:分 6:秒 7:ミリ秒)を指定する。
オプション書式変換時の以下のオプションを指定する。
+1桁揃えの前ゼロを付けない
+2下2桁のみの年を返す
+4英単語で月を返す
+8英単語で曜日を返す
+16英単語は正式名で返す

 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
	ll_libload wininet, "wininet.dll"
	ll_getproc InternetSetCookie, "InternetSetCookieA", wininet

#define global ctype leapchk(%1 = 1900) ((%1 \ 400 = 0) | ((%1 \ 4 = 0) & (%1 \ 100 ! 0)))
#module
#deffunc dateinit int, int, int
	mref year, 0 : mref month, 1 : mref day, 2
	days = 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
	kijun = year, month, day
	if year = 0 : kijun = 1900
	return

#deffunc adddays val, int
	if kijun = 0 : dateinit
	mref data, 48 : mref day, 1
	data = kijun, kijun.1, kijun.2
	if day < 0 {
		repeat -day / days
			if day + days + leapchk(data) <= 0 : break
			day += days + leapchk(data)
			data--
		loop
		repeat
			if data.2 + day > 0 : break
			if data.1 > 1 : data.1-- : else : data-- : data.1 = 12
			i = data.1
			day += (days.i + (data.1 = 2 & leapchk(data)))
		loop
		data.2 += day
	} else {
		repeat day / days
			if day - days + leapchk(data) <= 0 : break
			day -= (days + leapchk(data))
			data++
		loop
		if data.1 > 2 & (leapchk(data) = 0) : day++
		repeat
			i = data.1
			if data.2 + day <= (days.i + (data.1 = 2 & leapchk(data))) : break
			day -= (days.i + (data.1 = 2 & leapchk(data)))
			if data.1 < 12 : data.1++ : else : data++ : data.1 = 1
		loop
		data.2 += day
	}
	return

#deffunc setcookie val, str, int
	mref url, 24 : mref savedata, 33 : mref period, 2
	mref stt, 64
	strlen i, savedata
	sdim s, i + 50
	if period {
		dim date, 8
		gettime date.0, 0
		gettime date.1, 1
		gettime date.2, 3
		dateinit date.0, date.1, date.2
		adddays date, period
		i = date.0 - ((date.1 <= 2) * date.1), date.1 + ((date.1 <= 2) * 12), date.2
		date = date.0, date.1, i.0 + (i.0 / 4) - (i.0 / 100) + (i.0 / 400) + (i.1 * 13 + 8 / 5) + i.2 \ 7, i.2 // 曜日算出
		dateformat "%w, %d-%mo-%y %h:%mi:%s +0900", date, 4 + 8 // 強制的に日本時間
		s = savedata + "; expires = " + refstr
	} else {
		s = savedata
	}
	ll_getptr url : ll_ret prm.0
	prm.1 = 0
	ll_getptr s : ll_ret prm.2
	ll_callfunc prm, 3, InternetSetCookie@
	ll_ret i : stt = i
	return

#deffunc dateformat str, val, int
	sdim fmt, 4, 9
	sdim month, 10, 12
	sdim week, 10, 7
	mref format, 32 : mref date, 49 : mref option, 2
	mref rstr, 65
	fmt = "%y", "%mo", "%w", "%d", "%h", "%mi", "%s", "%ms"
	if option & 4 {
		if option & 16 {
			month.0 = "January", "February", "March", "April", "May", "June"
			month.6 = "July", "August", "September", "October", "November", "December"
		} else {
			month = "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
		}
	}
	if option & 8 {
		if option & 16 {
			week = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
		} else {
			week = "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
		}
	} else {
		week = "日", "月", "火", "水", "木", "金", "土"
	}
	rstr = format
	i.1 = 0
	repeat 9
		instr i.1, rstr, fmt.cnt, i.1
		if i.1 ! -1 {
			strlen i.2, fmt.cnt
			strlen i.3, rstr
			if option & 1 : s = "" + date.cnt : i = 4 : else : s = "00" + date.cnt
			if cnt = 0 & (option & 2 = 0) : i = 4 : else : if cnt = 7 : i = 3 : else : i = 2
			strmid s, s, -1, i
			if cnt = 1 & (option & 4 ! 0) : i = date.cnt - 1 : s = month.i
			if cnt = 2 : i = date.cnt : s = week.i
			strmid s1, rstr, , i.1
			strmid s2, rstr, i.1 + i.2, i.3 - i.1 - i.2
			rstr = s1 + s + s2
			continue cnt
		}
		i.1 = 0
	loop
	return
#global

	sdim address, 256
	sdim key, 12
	sdim buf, 1000
	address = "http://hspbc.jp/"
	key = "cookie_key"
	buf = "test_value"
	objsize 50, 25 : objmode 2
	pos  10, 15 : mes "URL"
	pos  40, 10 : input address, 540, 25
	pos 580, 10 : button "Set", *set
	pos  10, 50 : mesbox buf, 620, 420, 1
	stop

*set
	setcookie address, key + "=" + buf, 1
	if stat : dialog "クッキーに保存しました" : else : dialog "保存に失敗しました", 1
	stop

dateinit 基準年, 基準月, 基準日
基準年日付計算用の基準とする年を指定する。
基準月日付計算用の基準とする月を指定する。
基準日日付計算用の基準とする日を指定する。

adddays 受取先配列, 日数
受取先配列基準日から指定日数分を加減した日付の受取先配列を指定する。
要素0には演算後の年、要素1には演算後の月、要素2には演算後の日がセットされる。
日数加算または減算する日数を指定する。

setcookie URL, キー, データ, 期限
URL対象URLを指定する。
尚、内部でdateinit命令とadddays命令を使用しているため、
setcookie命令より前にdateinit命令とadddays命令を定義すること。
キー保存キーを指定する。尚、既に同一クッキー内に同一キーが存在する場合は上書きされる。
データ保存データを指定する。
期限ファイル保存しないセッションデータの場合を除き、有効期限日数を指定する。

受取先 = dateformat(書式文字列, 日時配列, オプション)
受取先書式付日時文字列の受取先を指定する。
書式文字列変換したい書式を指定する。
%yは年、%moは月、%wは曜、%dは日、%hは時、%miは分、%sは秒、%msはミリ秒に変換される。
日時配列変換元の数値を入れた配列変数(0:年 1:月 2:曜 3:日 4:時 5:分 6:秒 7:ミリ秒)を指定する。
オプション書式変換時の以下のオプションを指定する。
+1桁揃えの前ゼロを付けない
+2下2桁のみの年を返す
+4英単語で月を返す
+8英単語で曜日を返す
+16英単語は正式名で返す

 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
#uselib "wininet.dll"
#func  global InternetSetCookie "InternetSetCookieA" str, str, str

#define global ctype leapchk(%1 = 1900) ((%1 \ 400 = 0) | ((%1 \ 4 = 0) & (%1 \ 100 ! 0)))
#module
#deffunc dateinit int year, int month, int day
	days = 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
	kijun = year, month, day
	if year = 0 : kijun = 1900
	return

#deffunc adddays array data, int day, local i
	if kijun = 0 : dateinit
	i = day
	data = kijun, kijun.1, kijun.2
	if i < 0 {
		repeat -i / days
			if i + days + leapchk(data) <= 0 : break
			i += days + leapchk(data)
			data--
		loop
		repeat
			if data.2 + i > 0 : break
			if data.1 > 1 : data.1-- : else : data-- : data.1 = 12
			i += days(data.1) + (data.1 = 2 & leapchk(data))
		loop
		data.2 += i
	} else {
		repeat i / days
			if i - days + leapchk(data) <= 0 : break
			i -= days + leapchk(data)
			data++
		loop
		if data.1 > 2 & leapchk(data) = 0 : i++
		repeat
			if data.2 + i <= days(data.1) + (data.1 = 2 & leapchk(data)) : break
			i -= days(data.1) + (data.1 = 2 & leapchk(data))
			if data.1 < 12 : data.1++ : else : data++ : data.1 = 1
		loop
		data.2 += i
	}
	return

#deffunc setcookie str url, str savekey, str savedata, int period, local i, local s
	if period {
		dim date, 8
		date = gettime(0), gettime(1), gettime(3)
		dateinit date.0, date.1, date.2
		adddays date, period
		i = date.0 - (date.1 <= 2) * date.1, date.1 + (date.1 <= 2) * 12, date.2 // 曜日算出
		date = date.0, date.1, (i.0 + i.0 / 4 - i.0 / 100 + i.0 / 400 + (i.1 * 13 + 8) / 5 + i.2) \ 7, i.2
		s = savedata + "; expires = " + dateformat("%w, %d-%mo-%y %h:%mi:%s +0900", date, 4 + 8) // 強制的に日本時間
	} else {
		s = savedata
	}
	InternetSetCookie url, savekey, s
	return stat

#defcfunc dateformat str format, array date, int option, local i, local s, local rstr, local fmt
	fmt = "%y", "%mo", "%w", "%d", "%h", "%mi", "%s", "%ms"
	if option & 4 {
		if option & 16 {
			month.0 = "January", "February", "March", "April", "May", "June"
			month.6 = "July", "August", "September", "October", "November", "December"
		} else {
			month = "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
		}
	}
	if option & 8 {
		if option & 16 {
			week = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
		} else {
			week = "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
		}
	} else {
		week = "日", "月", "火", "水", "木", "金", "土"
	}
	rstr = format
	foreach fmt
		i = instr(rstr, , fmt.cnt)
		if i ! -1 {
			i.1 = strlen(fmt.cnt)
			if option & 1 : s = str(date.cnt) : else : s = strf("%02d", date.cnt)
			if cnt = 0 & (option & 2) ! 0 : s = strmid(s, -1, 2)
			if cnt = 1 & (option & 4) ! 0 : s = month(date.cnt - 1)
			if cnt = 2 : s = week(date.cnt)
			if cnt = 7 & (option & 1) = 0 : s = strf("%03d", date.cnt)
			rstr = strmid(rstr, 0, i) + s + strmid(rstr, i + i.1, strlen(rstr) - i - i.1)
			continue cnt
		}
	loop
	return rstr
#global

	sdim address, 256
	sdim key, 12
	sdim buf, 1000
	address = "http://hspbc.jp/"
	key = "cookie_key"
	buf = "test_value"
	objsize 50, 25 : objmode 2
	pos  10, 15 : mes "URL"
	pos  40, 10 : input address, 540, 25
	pos 580, 10 : button gosub "Set", *set
	pos  10, 50 : mesbox buf, 620, 420, 1
	stop

*set
	setcookie address, key, buf, 2
	if stat : dialog "クッキーに保存しました" : else : dialog "保存に失敗しました", 1
	return