1 | 'Classes/ActiveBasic/Strings/SPrintF.ab
|
---|
2 |
|
---|
3 | Namespace ActiveBasic
|
---|
4 | Namespace Strings
|
---|
5 |
|
---|
6 | Namespace Detail
|
---|
7 |
|
---|
8 | /*!
|
---|
9 | @brief 浮動小数点数を文字列化する低水準な関数。符号、指数、仮数に分けて出力。
|
---|
10 | @author Egtra
|
---|
11 | @date 2007/09/18
|
---|
12 | @param[in] x 文字列化する浮動小数点数
|
---|
13 | @param[out] e 指数
|
---|
14 | @param[out] sign 符号
|
---|
15 | @return 仮数
|
---|
16 | 仮数は1の位から下へ17桁で、小数点を含まない。そのため、誤差を無視すればVal(仮数) * 10 ^ (e - 17) = Abs(x)が成り立つ。
|
---|
17 |
|
---|
18 | xに無限大、非数を渡した場合の動作は未定義。
|
---|
19 | */
|
---|
20 | Function FloatToChars(x As Double, ByRef e As Long, ByRef sign As Boolean) As String
|
---|
21 | Imports System
|
---|
22 |
|
---|
23 | '0を弾く
|
---|
24 | If x = 0 Then
|
---|
25 | If GetQWord(VarPtr(x) As *QWord) And &h8000000000000000 Then
|
---|
26 | sign = True
|
---|
27 | Else
|
---|
28 | sign = False
|
---|
29 | End If
|
---|
30 |
|
---|
31 | e = 0
|
---|
32 | FloatToChars = "00000000000000000"
|
---|
33 | Exit Function
|
---|
34 | End If
|
---|
35 |
|
---|
36 | '符号の判断(同時に符号を取り除く)
|
---|
37 | If x < 0 Then
|
---|
38 | sign = True
|
---|
39 | x = -x
|
---|
40 | Else
|
---|
41 | sign = False
|
---|
42 | End If
|
---|
43 |
|
---|
44 | '1e16 <= x < 1e17へ正規化
|
---|
45 | '(元のx) = (正規化後のx) ^ (d - 17)である。
|
---|
46 | Dim d = Math.Floor(Math.Log10(x)) As Long
|
---|
47 | If d < 16 Then
|
---|
48 | x *= ipow(10, +17 - d)
|
---|
49 | ElseIf d > 16 Then
|
---|
50 | x /= ipow(10, -17 + d)
|
---|
51 | End If
|
---|
52 |
|
---|
53 | '補正
|
---|
54 | While x < 1e16
|
---|
55 | x *= 10
|
---|
56 | d--
|
---|
57 | Wend
|
---|
58 | While x >= 1e17
|
---|
59 | x /= 10
|
---|
60 | d++
|
---|
61 | Wend
|
---|
62 |
|
---|
63 | d--
|
---|
64 | e = d
|
---|
65 |
|
---|
66 | FloatToChars = FormatIntegerLU((x As Int64) As QWord, 17, 0, None)
|
---|
67 | End Function
|
---|
68 |
|
---|
69 | /*!
|
---|
70 | @brief 書式化関数群で使用するフラグ。
|
---|
71 | @author Egtra
|
---|
72 | @date 2007/09/18
|
---|
73 | */
|
---|
74 | Const Enum FormatFlags
|
---|
75 | '! 何も指定がない。
|
---|
76 | None = &h0
|
---|
77 | /*!
|
---|
78 | 符号、+。符号付変換[diAaEeFfGg]のとき、正の値でも符号を付ける。
|
---|
79 | AdjustFieldWidthの仕様から、Format関数郡内からAdjustFieldWidthにかけて、
|
---|
80 | 単に数値が符号付である(負の値である)ことを示す意味でも用いられる。
|
---|
81 | */
|
---|
82 | Sign = &h1
|
---|
83 | /*! 空白、空白文字。
|
---|
84 | 符号付変換[diAaEeFfGg]のとき、正の値ならば符号分の空白を開ける。Signが立っているときには無視される。
|
---|
85 | */
|
---|
86 | Blank = &h2
|
---|
87 | /*! ゼロ、0。
|
---|
88 | [diouXxAaEeFfGg]で、フィールドの空きを0で埋める。leftが立っているときには無視される。
|
---|
89 | */
|
---|
90 | Zero = &h4
|
---|
91 | '! 左揃え、-。フィールド内で左揃えにする。
|
---|
92 | LeftSide = &h8
|
---|
93 | /*! 代替表記、#。
|
---|
94 | <ul>
|
---|
95 | <li>[OoXx]では、値が0でない場合、先頭に0、0xを付ける。</ul>
|
---|
96 | <li>[AaEeFfGg]では、精度0でも小数点を付ける。</ul>
|
---|
97 | <li>[Gg]では、それに加え、小数部末尾の0の省略を行わないようにする。</ul>
|
---|
98 | </ul>
|
---|
99 | */
|
---|
100 | Alt = &h10
|
---|
101 | '! 大文字。使用するアルファベットを大文字にする。[aefgx]を[AEFGX]化する。
|
---|
102 | Cap = &h20
|
---|
103 |
|
---|
104 | '!BASIC接頭辞。&h, &oなど。
|
---|
105 | BPrefix = &h40
|
---|
106 |
|
---|
107 | /*!
|
---|
108 | 内部処理用に予約。
|
---|
109 | @note Minusとして使用されている。
|
---|
110 | */
|
---|
111 | Reserved = &h80000000
|
---|
112 | End Enum
|
---|
113 |
|
---|
114 | /*!
|
---|
115 | @brief 浮動小数点数をprintfの%e, %E(指数形式、十進法)相当の変換で文字列化する関数。
|
---|
116 | @author Egtra
|
---|
117 | @date 2007/09/18
|
---|
118 | @param[in] x 文字列化する浮動小数点数値。
|
---|
119 | @param[in] precision 精度。小数点以下の桁数。DWORD_MAXのとき、指定なしとして既定値6となる。
|
---|
120 | @param[in] field フィールド幅。
|
---|
121 | @param[in] flags 書式フラグ。
|
---|
122 | @return xの文字列表現
|
---|
123 |
|
---|
124 | @todo 他の実装での末尾桁の扱いを調べる(このコードでは何もしていないので切捨となっている)。
|
---|
125 | */
|
---|
126 | Function FormatFloatE(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
|
---|
127 | If precision = DWORD_MAX Then
|
---|
128 | precision = 6
|
---|
129 | End If
|
---|
130 |
|
---|
131 | Dim e As Long, negative As Boolean
|
---|
132 | Dim s = FloatToChars(x, e, negative)
|
---|
133 | Dim sb = FormatFloatE_Base(s, negative, precision, flags)
|
---|
134 | FormatFloatE_Exponent(sb, e, flags)
|
---|
135 | AdjustFieldWidth(sb, field, flags)
|
---|
136 | FormatFloatE = sb.ToString()
|
---|
137 | End Function
|
---|
138 |
|
---|
139 | /**
|
---|
140 | @brief FormatFloatEの符号・基数部の出力用。
|
---|
141 | @author Egtra
|
---|
142 | @date 2007/10/27
|
---|
143 | */
|
---|
144 | Function FormatFloatE_Base(s As String, negative As Boolean, precision As DWord, ByRef flags As FormatFlags) As System.Text.StringBuilder
|
---|
145 | FormatFloatE_Base = New System.Text.StringBuilder
|
---|
146 | With FormatFloatE_Base
|
---|
147 | AppendSign(FormatFloatE_Base, negative, flags)
|
---|
148 |
|
---|
149 | .Append(s[0])
|
---|
150 |
|
---|
151 | If (flags And Alt) Or precision > 0 Then
|
---|
152 | .Append(".")
|
---|
153 | Dim outputLen = s.Length - 1
|
---|
154 | If outputLen >= precision Then
|
---|
155 | .Append(s, 1, precision)
|
---|
156 | Else 'sで用意された桁が指定された精度より少ないとき
|
---|
157 | .Append(s, 1, outputLen)
|
---|
158 | .Append(&h30 As StrChar, precision - outputLen) '足りない桁は0埋め
|
---|
159 | End If
|
---|
160 | End If
|
---|
161 | End With
|
---|
162 | End Function
|
---|
163 |
|
---|
164 | /**
|
---|
165 | @brief FormatFloatEの指数部の出力用。
|
---|
166 | @author Egtra
|
---|
167 | @date 2007/10/27
|
---|
168 | */
|
---|
169 | Sub FormatFloatE_Exponent(buf As System.Text.StringBuilder, e As Long, flags As FormatFlags)
|
---|
170 | With buf
|
---|
171 | If flags And Cap Then
|
---|
172 | .Append("E")
|
---|
173 | Else
|
---|
174 | .Append("e")
|
---|
175 | End If
|
---|
176 | .Append(FormatIntegerD(e, 2, 0, Sign Or Zero))
|
---|
177 | End With
|
---|
178 | End Sub
|
---|
179 |
|
---|
180 | /*!
|
---|
181 | @brief 浮動小数点数をprintfの%f(小数形式、十進法)相当の変換で文字列化する関数。
|
---|
182 | @author Egtra
|
---|
183 | @date 2007/10/23
|
---|
184 | @param[in] x 文字列化する浮動小数点数値。
|
---|
185 | @param[in] precision 精度。小数点以下の桁数。DWORD_MAXのとき、指定なしとして既定値6となる。
|
---|
186 | @param[in] field フィールド幅。
|
---|
187 | @param[in] flags 書式フラグ。
|
---|
188 | @return xの文字列表現
|
---|
189 | */
|
---|
190 | Function FormatFloatF(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
|
---|
191 | If precision = DWORD_MAX Then
|
---|
192 | precision = 6
|
---|
193 | End If
|
---|
194 |
|
---|
195 | Dim e As Long, negative As Boolean
|
---|
196 | Dim s = FloatToChars(x, e, negative)
|
---|
197 | Dim sb = FormatFloatF_Core(s, e, negative, precision, flags)
|
---|
198 | AdjustFieldWidth(sb, field, flags)
|
---|
199 | FormatFloatF = sb.ToString()
|
---|
200 | End Function
|
---|
201 |
|
---|
202 | /**
|
---|
203 | @author Egtra
|
---|
204 | @date 2007/10/27
|
---|
205 | */
|
---|
206 | Function FormatFloatF_Core(s As String, e As Long, negative As Boolean, precision As DWord, ByRef flags As FormatFlags) As System.Text.StringBuilder
|
---|
207 | FormatFloatF_Core = New System.Text.StringBuilder
|
---|
208 | With FormatFloatF_Core
|
---|
209 | AppendSign(FormatFloatF_Core, negative, flags)
|
---|
210 |
|
---|
211 | Dim intPartLen = e + 1
|
---|
212 | Dim outputDigit = 0 As DWord
|
---|
213 | If intPartLen >= 17 Then
|
---|
214 | '有効桁が全て整数部に収まる場合
|
---|
215 | .Append(s)
|
---|
216 | .Append(&h30 As StrChar, intPartLen - 17)
|
---|
217 | outputDigit = 17
|
---|
218 | ElseIf intPartLen > 0 Then
|
---|
219 | '有効桁の一部が整数部にかかる場合
|
---|
220 | .Append(s, 0, intPartLen)
|
---|
221 | outputDigit = intPartLen
|
---|
222 | Else
|
---|
223 | '有効桁が全く整数部にかからない場合
|
---|
224 | .Append(&h30 As StrChar)
|
---|
225 | End If
|
---|
226 |
|
---|
227 | If precision > 0 Or (flags And Alt) Then
|
---|
228 | .Append(".")
|
---|
229 |
|
---|
230 | Dim lastDigit = s.Length - outputDigit
|
---|
231 | If lastDigit >= precision Then '変換して得られた文字列の桁数が精度以上ある場合
|
---|
232 | Dim zeroDigit = 0
|
---|
233 | If intPartLen < 0 Then
|
---|
234 | '1.23e-4 = 0.000123のように指数が負のため小数点以下に0が続く場合
|
---|
235 | zeroDigit = System.Math.Min(-intPartLen As DWord, precision)
|
---|
236 | .Append(&h30 As StrChar, zeroDigit As Long)
|
---|
237 | End If
|
---|
238 | .Append(s, outputDigit, (precision - zeroDigit) As Long)
|
---|
239 | Else
|
---|
240 | .Append(s, outputDigit, lastDigit)
|
---|
241 | .Append(&h30 As StrChar, (precision - lastDigit) As Long) '残りの桁は0埋め
|
---|
242 | End If
|
---|
243 | End If
|
---|
244 | End With
|
---|
245 | End Function
|
---|
246 |
|
---|
247 | /*!
|
---|
248 | @brief 浮動小数点数をprintfの%g, %G(小数・指数、十進法)相当の変換で文字列化する関数。
|
---|
249 | @author Egtra
|
---|
250 | @date 2007/10/23
|
---|
251 | @param[in] x 文字列化する浮動小数点数値。
|
---|
252 | @param[in] precision 精度。小数点以下の桁数。DWORD_MAXまたは0のとき、指定なしとして既定値6となる。
|
---|
253 | @param[in] field フィールド幅。
|
---|
254 | @param[in] flags 書式フラグ。
|
---|
255 | @return xの文字列表現
|
---|
256 | @todo 下位桁の扱いの調査。
|
---|
257 | */
|
---|
258 | Function FormatFloatG(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
|
---|
259 | 'GではE/Fと違い整数部も有効桁数に数えるのでその分を引いておく。
|
---|
260 | If precision = DWORD_MAX Or precision = 0 Then
|
---|
261 | precision = 5
|
---|
262 | Else
|
---|
263 | precision--
|
---|
264 | End If
|
---|
265 |
|
---|
266 | Dim e As Long, negative As Boolean
|
---|
267 | Dim s = FloatToChars(x, e, negative)
|
---|
268 |
|
---|
269 | Dim sb = Nothing As System.Text.StringBuilder
|
---|
270 |
|
---|
271 | If -5 < e And e < precision Then
|
---|
272 | sb = FormatFloatF_Core(s, e, negative, -e + precision, flags)
|
---|
273 | FormatFloatG_RemoveLowDigit(sb, flags)
|
---|
274 | Else
|
---|
275 | sb = FormatFloatE_Base(s, negative, precision, flags)
|
---|
276 | FormatFloatG_RemoveLowDigit(sb, flags)
|
---|
277 | FormatFloatE_Exponent(sb, e, flags)
|
---|
278 | End If
|
---|
279 |
|
---|
280 | AdjustFieldWidth(sb, field, flags)
|
---|
281 | FormatFloatG = sb.ToString()
|
---|
282 | End Function
|
---|
283 |
|
---|
284 | /*!
|
---|
285 | @brief FormatFloatG/A用の小数点以下末尾の0を削除するルーチン
|
---|
286 | @author Egtra
|
---|
287 | @date 2007/10/27
|
---|
288 | @param[in, out] sb 文字列バッファ
|
---|
289 | @param[in] flags フラグ
|
---|
290 | flagsでAltが立っているとき、この関数は何もしない。
|
---|
291 | */
|
---|
292 | Sub FormatFloatG_RemoveLowDigit(sb As System.Text.StringBuilder, flags As FormatFlags)
|
---|
293 | Imports ActiveBasic.Strings
|
---|
294 |
|
---|
295 | Dim count = sb.Length
|
---|
296 | If (flags And Alt) = 0 Then
|
---|
297 | Dim point = ChrFind(StrPtr(sb), count As SIZE_T, Asc("."))
|
---|
298 | If point = -1 Then
|
---|
299 | Debug
|
---|
300 | End If
|
---|
301 |
|
---|
302 | Dim i As Long
|
---|
303 | For i = count - 1 To point + 1 Step -1
|
---|
304 | If sb[i] <> &h30 Then
|
---|
305 | Exit For
|
---|
306 | End If
|
---|
307 | Next
|
---|
308 | If i <> point Then
|
---|
309 | i++
|
---|
310 | End If
|
---|
311 | sb.Length = i
|
---|
312 | End If
|
---|
313 | End Sub
|
---|
314 |
|
---|
315 | /*!
|
---|
316 | @brief 浮動小数点数をprintfの%a, %A(指数形式、十六進法)相当の変換で文字列化する関数。
|
---|
317 | @author Egtra
|
---|
318 | @date 2007/09/18
|
---|
319 | @param[in] x 文字列化する浮動小数点数値。
|
---|
320 | @param[in] precision 精度。小数点以下の桁数。DWORD_MAXのとき、指定なしとして既定値13となる。
|
---|
321 | @param[in] field フィールド幅。
|
---|
322 | @param[in] flags 書式フラグ。
|
---|
323 | @return xの文字列表現
|
---|
324 |
|
---|
325 | C99では、末尾の0を取り除いても良いとあるので、
|
---|
326 | このルーチンでは取り除くことにしている。
|
---|
327 | */
|
---|
328 | Function FormatFloatA(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
|
---|
329 | If precision = DWORD_MAX Then
|
---|
330 | precision = 13
|
---|
331 | End If
|
---|
332 |
|
---|
333 | Dim pqw = VarPtr(x) As *QWord
|
---|
334 |
|
---|
335 | Dim sb = New System.Text.StringBuilder
|
---|
336 | With sb
|
---|
337 | Dim sign = (GetQWord(pqw) And &H8000000000000000) As Boolean
|
---|
338 | pqw[0] And= &h7fffffffffffffff
|
---|
339 |
|
---|
340 | AppendSign(sb, sign, flags)
|
---|
341 |
|
---|
342 | If flags And BPrefix Then
|
---|
343 | .Append("&H")
|
---|
344 | Else
|
---|
345 | .Append("0X")
|
---|
346 | End If
|
---|
347 |
|
---|
348 | Dim biasedExp = (GetQWord(pqw) >> 52) As DWord And &h7FF
|
---|
349 | Dim exp As Long
|
---|
350 | If biasedExp = 0 Then
|
---|
351 | If GetQWord(pqw) <> 0 Then
|
---|
352 | exp = -1022 '非正規化数への対応
|
---|
353 | Else
|
---|
354 | exp = 0
|
---|
355 | End If
|
---|
356 | .Append("0")
|
---|
357 | Else
|
---|
358 | exp = biasedExp - 1023
|
---|
359 | .Append("1")
|
---|
360 | End If
|
---|
361 |
|
---|
362 | If precision > 0 Or (flags And Alt) Then
|
---|
363 | .Append(".")
|
---|
364 | Dim base = FormatIntegerLX(GetQWord(pqw) And &h000fffffffffffff, 13, 0, flags And Cap)
|
---|
365 | Dim diff = precision - 13 As Long
|
---|
366 | If diff <= 0 Then
|
---|
367 | .Append(Left$(base, precision))
|
---|
368 | Else
|
---|
369 | .Append(base).Append(&h30, diff)
|
---|
370 | End If
|
---|
371 | End If
|
---|
372 |
|
---|
373 | FormatFloatG_RemoveLowDigit(sb, flags)
|
---|
374 |
|
---|
375 | .Append("P")
|
---|
376 | .Append(FormatIntegerD(exp, 1, 0, Sign))
|
---|
377 |
|
---|
378 | FormatFloatA = .ToString()
|
---|
379 | End With
|
---|
380 |
|
---|
381 | If (flags And Cap) = 0 Then
|
---|
382 | FormatFloatA = FormatFloatA.ToLower()
|
---|
383 | End If
|
---|
384 | End Function
|
---|
385 |
|
---|
386 | /*!
|
---|
387 | @brief 先頭に符号もしくはその分の空白を出力する。FormatFloat用。
|
---|
388 | @author Egtra
|
---|
389 | @date 2007/10/23
|
---|
390 | @param[in, out] sb 出力先
|
---|
391 | @param[in] negative 符号
|
---|
392 | @param[in, out] flags フラグ。negative = Trueなら、Signを立てて返す。
|
---|
393 | */
|
---|
394 | Sub AppendSign(sb As System.Text.StringBuilder, negative As Boolean, ByRef flags As FormatFlags)
|
---|
395 | With sb
|
---|
396 | If negative Then
|
---|
397 | .Append("-")
|
---|
398 | flags Or= Sign
|
---|
399 | Else
|
---|
400 | If flags And Sign Then
|
---|
401 | .Append("+")
|
---|
402 | ElseIf flags And Blank Then
|
---|
403 | .Append(" ")
|
---|
404 | End If
|
---|
405 | End If
|
---|
406 | End With
|
---|
407 | End Sub
|
---|
408 |
|
---|
409 | /*!
|
---|
410 | @brief DWordの最大値4294967295の文字数 - 1。FormatIntegerU内で使用。
|
---|
411 | @author Egtra
|
---|
412 | @date 2007/09/18
|
---|
413 | */
|
---|
414 | Const MaxSizeU = 9
|
---|
415 |
|
---|
416 | /*!
|
---|
417 | @brief 符号無し整数をprintfの%u(十進法表現)相当の変換で文字列化する関数。
|
---|
418 | @author Egtra
|
---|
419 | @date 2007/09/18
|
---|
420 | @param[in] x 文字列化する整数値。
|
---|
421 | @param[in] d 精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
|
---|
422 | @param[in] field フィールド幅。
|
---|
423 | @param[in] flags 書式フラグ。
|
---|
424 | @return xの文字列表現
|
---|
425 | */
|
---|
426 | Function FormatIntegerU(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
427 | Return FormatIntegerEx(TraitsIntegerU[0], x, d, field, flags And (Not (Sign Or Blank)))
|
---|
428 | End Function
|
---|
429 |
|
---|
430 | /*!
|
---|
431 | @brief FormatIntegerUのQWord版
|
---|
432 | @author Egtra
|
---|
433 | @date 2007/10/26
|
---|
434 | */
|
---|
435 | Function FormatIntegerLU(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
436 | Return FormatIntegerEx(TraitsIntegerU[1], x, d, field, flags And (Not (Sign Or Blank)))
|
---|
437 | End Function
|
---|
438 |
|
---|
439 | /*!
|
---|
440 | @brief 符号有り整数をprintfの%d(十進法表現)相当の変換で文字列化する関数。
|
---|
441 | @author Egtra
|
---|
442 | @date 2007/10/13
|
---|
443 | @param[in] x 文字列化する整数値。
|
---|
444 | @param[in] d 精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
|
---|
445 | @param[in] field フィールド幅。
|
---|
446 | @param[in] flags 書式フラグ。
|
---|
447 | @return xの文字列表現
|
---|
448 | */
|
---|
449 | Function FormatIntegerD(x As Long, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
450 | Return FormatIntegerEx(TraitsIntegerD[0], (x As Int64) As QWord, d, field, flags)
|
---|
451 | End Function
|
---|
452 |
|
---|
453 | /*!
|
---|
454 | @brief FormatIntegerDのInt64版
|
---|
455 | @author Egtra
|
---|
456 | @date 2007/10/26
|
---|
457 | */
|
---|
458 | Function FormatIntegerLD(x As Int64, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
459 | Return FormatIntegerEx(TraitsIntegerD[1], x As QWord, d, field, flags)
|
---|
460 | End Function
|
---|
461 |
|
---|
462 | /*!
|
---|
463 | @author Egtra
|
---|
464 | @date 2007/10/26
|
---|
465 | */
|
---|
466 | Dim TraitsIntegerU[1] As IntegerConvertTraits
|
---|
467 | With TraitsIntegerU[0]
|
---|
468 | .Convert = AddressOf(IntegerU_Convert)
|
---|
469 | .Prefix = AddressOf(IntegerU_Prefix)
|
---|
470 | .MaxSize = MaxSizeU
|
---|
471 | End With
|
---|
472 |
|
---|
473 | With TraitsIntegerU[1]
|
---|
474 | .Convert = AddressOf(IntegerLU_Convert)
|
---|
475 | .Prefix = AddressOf(IntegerU_Prefix)
|
---|
476 | .MaxSize = MaxSizeLU
|
---|
477 | End With
|
---|
478 |
|
---|
479 | /*!
|
---|
480 | @author Egtra
|
---|
481 | @date 2007/10/28
|
---|
482 | */
|
---|
483 | Dim TraitsIntegerD[1] As IntegerConvertTraits
|
---|
484 | With TraitsIntegerD[0]
|
---|
485 | .Convert = AddressOf(IntegerD_Convert)
|
---|
486 | .Prefix = AddressOf(IntegerD_Prefix)
|
---|
487 | .MaxSize = MaxSizeU
|
---|
488 | End With
|
---|
489 |
|
---|
490 | With TraitsIntegerD[1]
|
---|
491 | .Convert = AddressOf(IntegerLD_Convert)
|
---|
492 | .Prefix = AddressOf(IntegerD_Prefix)
|
---|
493 | .MaxSize = MaxSizeLU
|
---|
494 | End With
|
---|
495 |
|
---|
496 | /*!
|
---|
497 | @brief 負数を表すフラグ。FormatIntegerD, LDからIntegerDU_Prefixまでの内部処理用。
|
---|
498 | @author Egtra
|
---|
499 | @date 2007/10/26
|
---|
500 | */
|
---|
501 | Const Minus = Reserved
|
---|
502 |
|
---|
503 | /*!
|
---|
504 | @author Egtra
|
---|
505 | @date 2007/10/26
|
---|
506 | */
|
---|
507 | Function IntegerU_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
|
---|
508 | Dim x = xq As DWord
|
---|
509 | Dim i = MaxSizeU
|
---|
510 | While x <> 0
|
---|
511 | buf[i] = (x As Int64 Mod 10 + &h30) As StrChar 'Int64への型変換は#117対策
|
---|
512 | x \= 10
|
---|
513 | i--
|
---|
514 | Wend
|
---|
515 | Return i
|
---|
516 | End Function
|
---|
517 |
|
---|
518 | /*!
|
---|
519 | @brief IntegerU_ConvertのQWord版
|
---|
520 | @author Egtra
|
---|
521 | @date 2007/10/26
|
---|
522 | @bug #117のため、現在Int64の最大値を超える値を正しく処理できない。
|
---|
523 | */
|
---|
524 | Function IntegerLU_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
|
---|
525 | Dim i = MaxSizeLU
|
---|
526 | While x <> 0
|
---|
527 | buf[i] = (x As Int64 Mod 10 + &h30) As StrChar 'Int64への型変換は#117対策
|
---|
528 | x \= 10
|
---|
529 | i--
|
---|
530 | Wend
|
---|
531 | Return i
|
---|
532 | End Function
|
---|
533 |
|
---|
534 | /*!
|
---|
535 | @author Egtra
|
---|
536 | @date 2007/10/26
|
---|
537 | */
|
---|
538 | Function IntegerU_Prefix(x As QWord, flags As FormatFlags) As String
|
---|
539 | End Function
|
---|
540 |
|
---|
541 | /*!
|
---|
542 | @author Egtra
|
---|
543 | @date 2007/10/28
|
---|
544 | */
|
---|
545 | Function IntegerD_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
|
---|
546 | Return IntegerU_Convert(buf, Abs((xq As DWord) As Long) As DWord, flags)
|
---|
547 | End Function
|
---|
548 |
|
---|
549 | /*!
|
---|
550 | @brief IntegerD_ConvertのInt64版
|
---|
551 | @author Egtra
|
---|
552 | @date 2007/10/28
|
---|
553 | */
|
---|
554 | Function IntegerLD_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
|
---|
555 | Return IntegerLU_Convert(buf, Abs(x As Int64) As QWord, flags)
|
---|
556 | End Function
|
---|
557 |
|
---|
558 | /*!
|
---|
559 | @author Egtra
|
---|
560 | @date 2007/10/28
|
---|
561 | */
|
---|
562 | Function IntegerD_Prefix(x As QWord, flags As FormatFlags) As String
|
---|
563 | If (x As Int64) < 0 Then
|
---|
564 | IntegerD_Prefix = "-"
|
---|
565 | ElseIf flags And Sign Then
|
---|
566 | IntegerD_Prefix = "+"
|
---|
567 | ElseIf flags And Blank Then
|
---|
568 | IntegerD_Prefix = " "
|
---|
569 | End If
|
---|
570 | End Function
|
---|
571 |
|
---|
572 | /*!
|
---|
573 | @brief DWordの最大値の八進法表現37777777777の文字数 - 1 + 1。IntegerO_Convert内で使用。
|
---|
574 | @author Egtra
|
---|
575 | @date 2007/10/19
|
---|
576 | 上の式で1を加えているのは、八進接頭辞の分。
|
---|
577 | */
|
---|
578 | Const MaxSizeO = 11
|
---|
579 |
|
---|
580 | /*!
|
---|
581 | @brief QWordの最大値の八進法表現1777777777777777777777の文字数 - 1 + 1。IntegerO_Convert内で使用。
|
---|
582 | @author Egtra
|
---|
583 | @date 2007/10/26
|
---|
584 | 上の式で1を加えているのは、八進接頭辞の分。
|
---|
585 | */
|
---|
586 | Const MaxSizeLO = 22
|
---|
587 |
|
---|
588 | /*!
|
---|
589 | @author Egtra
|
---|
590 | @date 2007/10/22
|
---|
591 | */
|
---|
592 | Dim TraitsIntegerO[1] As IntegerConvertTraits
|
---|
593 | With TraitsIntegerO[0]
|
---|
594 | .Convert = AddressOf(IntegerO_Convert)
|
---|
595 | .Prefix = AddressOf(IntegerO_Prefix)
|
---|
596 | .MaxSize = MaxSizeO
|
---|
597 | End With
|
---|
598 |
|
---|
599 | With TraitsIntegerO[1]
|
---|
600 | .Convert = AddressOf(IntegerLO_Convert)
|
---|
601 | .Prefix = AddressOf(IntegerO_Prefix)
|
---|
602 | .MaxSize = MaxSizeLO
|
---|
603 | End With
|
---|
604 |
|
---|
605 | /*!
|
---|
606 | @brief 符号無し整数をprintfの%o(八進法表現)相当の変換で文字列化する関数。
|
---|
607 | @author Egtra
|
---|
608 | @date 2007/10/19
|
---|
609 | @param[in] x 文字列化する整数値。
|
---|
610 | @param[in] d 精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
|
---|
611 | @param[in] field フィールド幅。
|
---|
612 | @param[in] flags 書式フラグ。
|
---|
613 | @return xの文字列表現
|
---|
614 | */
|
---|
615 | Function FormatIntegerO(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
616 | Return FormatIntegerEx(TraitsIntegerO[0], x, d, field, flags)
|
---|
617 | End Function
|
---|
618 |
|
---|
619 | /*!
|
---|
620 | @brief FormatIntegerOのQWord版。
|
---|
621 | @author Egtra
|
---|
622 | @date 2007/10/26
|
---|
623 | */
|
---|
624 | Function FormatIntegerLO(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
625 | Return FormatIntegerEx(TraitsIntegerO[1], x, d, field, flags)
|
---|
626 | End Function
|
---|
627 |
|
---|
628 | /*!
|
---|
629 | @author Egtra
|
---|
630 | @date 2007/10/22
|
---|
631 | */
|
---|
632 | Function IntegerO_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
|
---|
633 | Dim x = xq As DWord
|
---|
634 | Dim i = MaxSizeO
|
---|
635 | While x <> 0
|
---|
636 | buf[i] = ((x And &o7) + &h30) As StrChar
|
---|
637 | x >>= 3
|
---|
638 | i--
|
---|
639 | Wend
|
---|
640 | If flags And Alt Then
|
---|
641 | buf[i] = &h30
|
---|
642 | i--
|
---|
643 | End If
|
---|
644 | Return i
|
---|
645 | End Function
|
---|
646 |
|
---|
647 | /*!
|
---|
648 | @brief IntegerO_ConvertのQWord版。
|
---|
649 | @author Egtra
|
---|
650 | @date 2007/10/26
|
---|
651 | */
|
---|
652 | Function IntegerLO_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
|
---|
653 | Dim i = MaxSizeLO
|
---|
654 | While x <> 0
|
---|
655 | buf[i] = ((x And &o7) + &h30) As StrChar
|
---|
656 | x >>= 3
|
---|
657 | i--
|
---|
658 | Wend
|
---|
659 | If flags And Alt Then
|
---|
660 | buf[i] = &h30
|
---|
661 | i--
|
---|
662 | End If
|
---|
663 | Return i
|
---|
664 | End Function
|
---|
665 |
|
---|
666 | /*!
|
---|
667 | @author Egtra
|
---|
668 | @date 2007/10/22
|
---|
669 | @note #フラグ (Alt)の処理は、IntegerO/LO_Convert内で行うので、ここで処理することはない。
|
---|
670 | */
|
---|
671 | Function IntegerO_Prefix(x As QWord, flags As FormatFlags) As String
|
---|
672 | If flags And BPrefix Then
|
---|
673 | If x <> 0 Then
|
---|
674 | IntegerO_Prefix = "&O"
|
---|
675 | End If
|
---|
676 | End If
|
---|
677 | End Function
|
---|
678 |
|
---|
679 | /*!
|
---|
680 | @brief DWordの最大値の十六進法表現ffffffffの文字数 - 1。FormatIntegerO内で使用。
|
---|
681 | @author Egtra
|
---|
682 | @date 2007/10/24
|
---|
683 | */
|
---|
684 | Const MaxSizeX = 7
|
---|
685 |
|
---|
686 | /*!
|
---|
687 | @brief QWordの最大値の十六進法表現ffffffffffffffffの文字数 - 1。FormatIntegerO内で使用。
|
---|
688 | @author Egtra
|
---|
689 | @date 2007/10/26
|
---|
690 | */
|
---|
691 | Const MaxSizeLX = 15
|
---|
692 |
|
---|
693 | /*!
|
---|
694 | @author Egtra
|
---|
695 | @date 2007/10/24
|
---|
696 | */
|
---|
697 | Dim TraitsIntegerX[1] As IntegerConvertTraits
|
---|
698 | With TraitsIntegerX[0]
|
---|
699 | .Convert = AddressOf(IntegerX_Convert)
|
---|
700 | .Prefix = AddressOf(IntegerX_Prefix)
|
---|
701 | .MaxSize = MaxSizeX
|
---|
702 | End With
|
---|
703 |
|
---|
704 | With TraitsIntegerX[1]
|
---|
705 | .Convert = AddressOf(IntegerLX_Convert)
|
---|
706 | .Prefix = AddressOf(IntegerX_Prefix)
|
---|
707 | .MaxSize = MaxSizeLX
|
---|
708 | End With
|
---|
709 |
|
---|
710 | /*!
|
---|
711 | @brief 整数をprintfの%x, %X(十六進法)相当の変換で文字列化する関数。
|
---|
712 | @author Egtra
|
---|
713 | @date 2007/10/19
|
---|
714 | @param[in] x 文字列化する整数値。
|
---|
715 | @param[in] d 精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
|
---|
716 | @param[in] field フィールド幅。
|
---|
717 | @param[in] flags 書式フラグ。
|
---|
718 | @return xの文字列表現
|
---|
719 | */
|
---|
720 | Function FormatIntegerX(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
721 | Return FormatIntegerEx(TraitsIntegerX[0], x, d, field, flags)
|
---|
722 | End Function
|
---|
723 |
|
---|
724 | /*!
|
---|
725 | @brief FormatIntegerXのQWord版。
|
---|
726 | @author Egtra
|
---|
727 | @date 2007/10/22
|
---|
728 | */
|
---|
729 | Function FormatIntegerLX(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
730 | Return FormatIntegerEx(TraitsIntegerX[1], x, d, field, flags)
|
---|
731 | End Function
|
---|
732 |
|
---|
733 | /*
|
---|
734 | @brief 0からFまでの文字を収めた表
|
---|
735 | @author egtra
|
---|
736 | */
|
---|
737 | Dim HexadecimalTable[&h10] = [&h30, &h31, &h32, &h33, &h34, &h35, &h36, &h37, &h38, &h39, &h41, &h42, &h43, &h44, &h45, &h46] As Byte
|
---|
738 |
|
---|
739 | /*!
|
---|
740 | @author Egtra
|
---|
741 | @date 2007/10/22
|
---|
742 | */
|
---|
743 | Function IntegerX_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
|
---|
744 | Dim i = MaxSizeX
|
---|
745 | Dim x = xq As DWord
|
---|
746 | While x <> 0
|
---|
747 | buf[i] = HexadecimalTable[x And &h0f]
|
---|
748 | x >>= 4
|
---|
749 | i--
|
---|
750 | Wend
|
---|
751 | Return i
|
---|
752 | End Function
|
---|
753 |
|
---|
754 | /*!
|
---|
755 | @brief IntegerX_ConvertのQWord版。
|
---|
756 | @author Egtra
|
---|
757 | @date 2007/10/22
|
---|
758 | */
|
---|
759 | Function IntegerLX_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
|
---|
760 | Dim i = MaxSizeLX
|
---|
761 | While x <> 0
|
---|
762 | buf[i] = HexadecimalTable[x And &h0f]
|
---|
763 | x >>= 4
|
---|
764 | i--
|
---|
765 | Wend
|
---|
766 | Return i
|
---|
767 | End Function
|
---|
768 |
|
---|
769 | /*!
|
---|
770 | @author Egtra
|
---|
771 | @date 2007/10/24
|
---|
772 | */
|
---|
773 | Function IntegerX_Prefix(x As QWord, flags As FormatFlags) As String
|
---|
774 | If x <> 0 Then
|
---|
775 | If flags And Alt Then
|
---|
776 | IntegerX_Prefix = "0X"
|
---|
777 | ElseIf flags And BPrefix Then
|
---|
778 | IntegerX_Prefix = "&H"
|
---|
779 | End If
|
---|
780 | End If
|
---|
781 | End Function
|
---|
782 |
|
---|
783 | /*!
|
---|
784 | @brief FormatIntegerExへ渡す変換特性を表す構造体型。
|
---|
785 | @author Egtra
|
---|
786 | @date 2007/10/22
|
---|
787 |
|
---|
788 | FormatIntegerの都合上、このファイル内で宣言しているIntegerConvertTraits型の
|
---|
789 | 変数は全て配列となっている;[0]が32ビット変換、[1]が64ビット変換である。
|
---|
790 | */
|
---|
791 | Type IntegerConvertTraits
|
---|
792 | '!変換を行う関数へのポインタ。
|
---|
793 | Convert As *Function(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
|
---|
794 | '!接頭辞を取得する関数へのポインタ。
|
---|
795 | Prefix As *Function(x As QWord, flags As FormatFlags) As String
|
---|
796 | '!必要なバッファの大きさ。
|
---|
797 | MaxSize As DWord
|
---|
798 | End Type
|
---|
799 |
|
---|
800 | /*!
|
---|
801 | @brief 整数変換全てを行う関数。これを雛形とし、形式毎の差異はIntegerConvertTraitsで表現する。
|
---|
802 | @author Egtra
|
---|
803 | @date 2007/10/22
|
---|
804 | @param[in] tr 特性情報。
|
---|
805 | @param[in] x 変換元の数値。
|
---|
806 | @param[in] d 精度。ここでは最低限出力する桁数。
|
---|
807 | @param[in] field フィールド幅。
|
---|
808 | @param[in] flags フラグ。
|
---|
809 | */
|
---|
810 | Function FormatIntegerEx(ByRef tr As IntegerConvertTraits, x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
811 | If d = DWORD_MAX Then
|
---|
812 | d = 1
|
---|
813 | Else
|
---|
814 | '精度が指定されているとき、ゼロフラグは無視される。
|
---|
815 | '仕様上、左揃えのときも無視されるが、それはAdjustFieldWidthが行ってくれる。
|
---|
816 | flags And= Not Zero
|
---|
817 | End If
|
---|
818 |
|
---|
819 | Dim sb = New System.Text.StringBuilder
|
---|
820 | If sb.Length = &hfeeefeee Then Debug
|
---|
821 | With sb
|
---|
822 | Dim prefixFunc = tr.Prefix
|
---|
823 | Dim prefix = prefixFunc(x, flags)
|
---|
824 | sb.Append(prefix)
|
---|
825 | If sb.Length = &hfeeefeee Then Debug
|
---|
826 |
|
---|
827 | Dim prefixLen = 0 As DWord
|
---|
828 | If String.IsNullOrEmpty(prefix) = False Then
|
---|
829 | prefixLen = prefix.Length As DWord
|
---|
830 | End If
|
---|
831 |
|
---|
832 | Dim buf = GC_malloc_atomic((tr.MaxSize + 1) * SizeOf (StrChar)) As *StrChar
|
---|
833 | Dim convertFunc = tr.Convert
|
---|
834 | Dim bufStartPos = convertFunc(buf, x, flags)
|
---|
835 |
|
---|
836 | If sb.Length = &hfeeefeee Then Debug
|
---|
837 | Dim len = (tr.MaxSize - bufStartPos) As Long
|
---|
838 | If len < 0 Then
|
---|
839 | Debug
|
---|
840 | End If
|
---|
841 | If len < d Then
|
---|
842 | .Append(&h30 As StrChar, d - len)
|
---|
843 | End If
|
---|
844 |
|
---|
845 | .Append(buf, bufStartPos + 1, len)
|
---|
846 | If sb.Length = &hfeeefeee Then Debug
|
---|
847 |
|
---|
848 | AdjustFieldWidth(sb, field, flags And (Not (Sign Or Blank)), prefixLen)
|
---|
849 | If sb.Length = &hfeeefeee Then Debug
|
---|
850 | End With
|
---|
851 | FormatIntegerEx = sb.ToString()
|
---|
852 |
|
---|
853 | If (flags And Cap) = 0 Then
|
---|
854 | FormatIntegerEx = FormatIntegerEx.ToLower()
|
---|
855 | End If
|
---|
856 | End Function
|
---|
857 |
|
---|
858 | /*!
|
---|
859 | @brief QWordの最大値18446744073709551615の文字数 - 1。FormatIntegerLU内で使用。
|
---|
860 | @author Egtra
|
---|
861 | @date 2007/09/18
|
---|
862 | */
|
---|
863 | Const MaxSizeLU = 19
|
---|
864 |
|
---|
865 | /*!
|
---|
866 | @brief 文字列をフィールド幅まで満たされるように空白などを挿入する。
|
---|
867 | @author Egtra
|
---|
868 | @date 2007/10/13
|
---|
869 | @param[in,out] sb 対象文字列
|
---|
870 | @param[in] field フィールド幅
|
---|
871 | @param[in] hasSign 符号を持っている(負の値か)か否か
|
---|
872 | @param[in] flags フラグ
|
---|
873 | @param[in] prefixLen (あれば)接頭辞の文字数。ゼロ埋めする際、この数だけ挿入位置を後ろにする。
|
---|
874 | sbが"-1"のように負符号を持っている場合は、呼出元でSignフラグ(またはBlank)を立てること。
|
---|
875 | */
|
---|
876 | Sub AdjustFieldWidth(sb As System.Text.StringBuilder, field As DWord, flags As FormatFlags, prefixLen = 0 As DWord)
|
---|
877 | With sb
|
---|
878 | If .Length < field Then
|
---|
879 | Dim embeddedSize = field - .Length
|
---|
880 | If flags And LeftSide Then
|
---|
881 | .Append(&h20, embeddedSize)
|
---|
882 | Else
|
---|
883 | Dim insPos As Long
|
---|
884 | If (flags And Zero) <> 0 Then
|
---|
885 | If (flags And Blank) Or (flags And Sign) Then
|
---|
886 | insPos++
|
---|
887 | End If
|
---|
888 | insPos += prefixLen
|
---|
889 | .Insert(insPos, String$(embeddedSize, "0"))
|
---|
890 | Else
|
---|
891 | .Insert(insPos, String$(embeddedSize, " "))
|
---|
892 | End If
|
---|
893 | End If
|
---|
894 | End If
|
---|
895 | End With
|
---|
896 | End Sub
|
---|
897 |
|
---|
898 | /*!
|
---|
899 | @brief 文字列をprintfの%s相当の変換で書式化する関数。
|
---|
900 | @author Egtra
|
---|
901 | @date 2007/10/27
|
---|
902 | @param[in] x 文字列。
|
---|
903 | @param[in] d 精度、最大の文字数。
|
---|
904 | @param[in] field フィールド幅。
|
---|
905 | @param[in] flags 書式フラグ。
|
---|
906 | @return 書式化された文字列。
|
---|
907 | */
|
---|
908 | Function FormatString(x As String, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
909 | Dim sb = New System.Text.StringBuilder(
|
---|
910 | x, 0, System.Math.Min(x.Length As DWord, d) As Long, field)
|
---|
911 | AdjustFieldWidth(sb, field, flags And LeftSide)
|
---|
912 | FormatString = sb.ToString()
|
---|
913 | End Function
|
---|
914 |
|
---|
915 | /*!
|
---|
916 | @brief 文字をprintfの%c相当の変換で書式化する関数。
|
---|
917 | @author Egtra
|
---|
918 | @date 2007/10/27
|
---|
919 | @param[in] x 文字。
|
---|
920 | @param[in] d 精度、最大の文字数。
|
---|
921 | @param[in] field フィールド幅。
|
---|
922 | @param[in] flags 書式フラグ。
|
---|
923 | @return 書式化された文字列。
|
---|
924 | */
|
---|
925 | Function FormatCharacter(x As StrChar, d As DWord, field As DWord, flags As FormatFlags) As String
|
---|
926 | Dim sb = New System.Text.StringBuilder(field + 1)
|
---|
927 | sb.Append(x)
|
---|
928 | AdjustFieldWidth(sb, field, flags And LeftSide)
|
---|
929 | FormatCharacter = sb.ToString()
|
---|
930 | End Function
|
---|
931 |
|
---|
932 | /*!
|
---|
933 | @author Egtra
|
---|
934 | @date 2007/10/28
|
---|
935 | */
|
---|
936 | TypeDef FormatFloatProc = *Function(x As Double, precision As DWord, fieldWidth As DWord, flags As FormatFlags) As String
|
---|
937 |
|
---|
938 | /*!
|
---|
939 | @brief SPrintfから呼ばれる浮動小数点数用書式文字列化関数
|
---|
940 | @author Egtra
|
---|
941 | @date 2007/10/28
|
---|
942 | */
|
---|
943 | Sub FormatFloat(s As System.Text.StringBuilder, formatProc As FormatFloatProc,
|
---|
944 | param As Object, precision As DWord, field As DWord, flags As FormatFlags)
|
---|
945 |
|
---|
946 | Dim x As Double
|
---|
947 | Dim typeName = param.GetType().FullName
|
---|
948 | If typeName = "System.Double" Then
|
---|
949 | x = param As System.Double
|
---|
950 | ElseIf typeName = "System.Single" Then
|
---|
951 | x = param As System.Single
|
---|
952 | End If
|
---|
953 | s.Append(formatProc(x, precision, field, flags))
|
---|
954 | End Sub
|
---|
955 |
|
---|
956 | /*!
|
---|
957 | @brief SPrintfから呼ばれる整数用書式文字列化関数
|
---|
958 | @author Egtra
|
---|
959 | @date 2007/10/28
|
---|
960 | */
|
---|
961 | Sub FormatInteger(s As System.Text.StringBuilder, traits As *IntegerConvertTraits,
|
---|
962 | param As Object, signed As Boolean, typeWidth As Long, precision As DWord, field As DWord, flags As FormatFlags)
|
---|
963 |
|
---|
964 | Dim x As QWord
|
---|
965 | Dim typeName = param.GetType().FullName
|
---|
966 | If typeName = "System.UInt64" Then
|
---|
967 | x = param As System.UInt64
|
---|
968 | ElseIf typeName = "System.Int64" Then
|
---|
969 | x = (param As System.Int64) As QWord
|
---|
970 | ElseIf typeName = "System.UInt32" Then
|
---|
971 | x = param As System.UInt32
|
---|
972 | ElseIf typeName = "System.Int32" Then
|
---|
973 | x = (param As System.Int32) As QWord
|
---|
974 | ElseIf typeName = "System.UInt16" Then
|
---|
975 | x = param As System.UInt16
|
---|
976 | ElseIf typeName = "System.Int16" Then
|
---|
977 | x = (param As System.Int16) As QWord
|
---|
978 | ElseIf typeName = "System.UInt8" Then
|
---|
979 | x = param As System.Byte
|
---|
980 | ElseIf typeName = "System.Int8" Then
|
---|
981 | x = (param As System.SByte) As QWord
|
---|
982 | End If
|
---|
983 | '一旦縮めた後、符号・ゼロ拡張させる。
|
---|
984 | 'また、64ビット整数なら64ビット変換Traitsを選択する。
|
---|
985 | If signed Then
|
---|
986 | If typeWidth = 1 Then
|
---|
987 | traits = VarPtr(traits[1])
|
---|
988 | ElseIf typeWidth = 0 Then
|
---|
989 | x = (((x As DWord) As Long) As Int64) As QWord
|
---|
990 | ElseIf typeWidth = -1 Then
|
---|
991 | x = (((x As Word) As Integer) As Int64) As QWord
|
---|
992 | ElseIf typeWidth = -2 Then
|
---|
993 | x = (((x As Byte) As SByte) As Int64) As QWord
|
---|
994 | End If
|
---|
995 | Else
|
---|
996 | If typeWidth = 1 Then
|
---|
997 | traits = VarPtr(traits[1])
|
---|
998 | ElseIf typeWidth = 0 Then
|
---|
999 | x = x As DWord
|
---|
1000 | ElseIf typeWidth = -1 Then
|
---|
1001 | x = x As Word
|
---|
1002 | ElseIf typeWidth = -2 Then
|
---|
1003 | x = x As Byte
|
---|
1004 | End If
|
---|
1005 | End If
|
---|
1006 |
|
---|
1007 | s.Append(FormatIntegerEx(ByVal traits, x, precision, field, flags))
|
---|
1008 | End Sub
|
---|
1009 |
|
---|
1010 | 'Format関数群ここまで
|
---|
1011 | '----
|
---|
1012 |
|
---|
1013 | /*!
|
---|
1014 | @brief 文字列から数値への変換。さらに変換に使われなかった文字列の位置を返す。
|
---|
1015 | @author Egtra
|
---|
1016 | @date 2007/11/11
|
---|
1017 | @param[in] s 変換する文字
|
---|
1018 | @param[out] p 変換に使われなかった部分の先頭を指すポインタ
|
---|
1019 | @return 変換して得られた数値。変換できなければ0。
|
---|
1020 | */
|
---|
1021 | Function StrToLong(s As *StrChar, ByRef p As *StrChar) As Long
|
---|
1022 | Dim negative As Boolean
|
---|
1023 | Dim i = 0 As Long
|
---|
1024 | If s[i] = &h2d Then 'Asc("-")
|
---|
1025 | i++
|
---|
1026 | negative = True
|
---|
1027 | End If
|
---|
1028 | Do
|
---|
1029 | Dim c = s[i]
|
---|
1030 | If Not IsDigit(c) Then Exit Do
|
---|
1031 | StrToLong *= 10
|
---|
1032 | StrToLong += ((c As DWord) And &h0f) As Long
|
---|
1033 | i++
|
---|
1034 | Loop
|
---|
1035 | If negative Then
|
---|
1036 | StrToLong = -StrToLong
|
---|
1037 | End If
|
---|
1038 | p = VarPtr(s[i])
|
---|
1039 | End Function
|
---|
1040 |
|
---|
1041 | /*!
|
---|
1042 | @brief 文字が十進数字かどうか調べる。
|
---|
1043 | @author Egtra
|
---|
1044 | @date 2007/11/11
|
---|
1045 | @param[in] c 調べる文字
|
---|
1046 | @retval True 0から9の文字である
|
---|
1047 | @retval False そうでない
|
---|
1048 | */
|
---|
1049 | Function IsDigit(c As StrChar) As Boolean
|
---|
1050 | Dim dw = (c As DWord)
|
---|
1051 | IsDigit = (dw - &h30) < 10
|
---|
1052 | End Function
|
---|
1053 |
|
---|
1054 | /*!
|
---|
1055 | @brief フィールド幅、精度用の数値読取
|
---|
1056 | @author Egtra
|
---|
1057 | @date 2007/11/11
|
---|
1058 | @param[in, out] fmt 読み途中の書式指定
|
---|
1059 | @param[in] params
|
---|
1060 | @param[in, out] paramsCount
|
---|
1061 | @param[out] ret 読み取った数値。読み取られなかったときの値は不定。
|
---|
1062 | @retval True 読取を行った
|
---|
1063 | @retval False 行わなかった
|
---|
1064 | fmt[0]が*のときにはparamsから1つ読み取る。
|
---|
1065 | そうでなく、fmtに数字(先頭に-符号があっても可)が並んでいれば、それを読み取る。
|
---|
1066 | */
|
---|
1067 | Function ReadInt(ByRef fmt As *StrChar, params As *Object, ByRef paramsCount As SIZE_T, ByRef ret As Long) As Boolean
|
---|
1068 | If fmt[0] = &h2a Then '*
|
---|
1069 | fmt = VarPtr(fmt[1]) 'po
|
---|
1070 | ret = params[paramsCount] As System.Int32
|
---|
1071 | paramsCount++
|
---|
1072 | ReadInt = True
|
---|
1073 | Else
|
---|
1074 | Dim p As *StrChar
|
---|
1075 | ret = StrToLong(fmt, p)
|
---|
1076 | If fmt <> p Then
|
---|
1077 | fmt = p
|
---|
1078 | ReadInt = True
|
---|
1079 | Else
|
---|
1080 | ReadInt = False
|
---|
1081 | End If
|
---|
1082 | End If
|
---|
1083 | End Function
|
---|
1084 |
|
---|
1085 | /*!
|
---|
1086 | @brief フラグ指定の読み込み
|
---|
1087 | @author Egtra
|
---|
1088 | @date 2007/10/28
|
---|
1089 | @param[in, out] fmt
|
---|
1090 | @param[out] flags
|
---|
1091 | @retval True 読み込みが完了した。
|
---|
1092 | @retval False 読み取り中に文字列が終了した(ヌル文字が現れた)。
|
---|
1093 | */
|
---|
1094 | Function ReadFlags(ByRef fmt As *StrChar, ByRef flags As FormatFlags) As Boolean
|
---|
1095 | ReadFlags = False
|
---|
1096 | Do
|
---|
1097 | Select Case fmt[0]
|
---|
1098 | Case &h23 '#
|
---|
1099 | flags Or= Alt
|
---|
1100 | Case &h30 '0
|
---|
1101 | flags Or= Zero
|
---|
1102 | Case &h20 '空白
|
---|
1103 | flags Or= Blank
|
---|
1104 | Case &h2b '+
|
---|
1105 | flags Or= Sign
|
---|
1106 | Case &h2d '-
|
---|
1107 | flags Or = LeftSide
|
---|
1108 | Case &h26 '&
|
---|
1109 | flags Or= BPrefix
|
---|
1110 | Case 0
|
---|
1111 | Exit Function
|
---|
1112 | Case Else
|
---|
1113 | Exit Do
|
---|
1114 | End Select
|
---|
1115 | fmt = VarPtr(fmt[1]) 'po
|
---|
1116 | Loop
|
---|
1117 | ReadFlags = True
|
---|
1118 | End Function
|
---|
1119 |
|
---|
1120 | /*!
|
---|
1121 | @brief フィールド幅指定の読み込み
|
---|
1122 | @author Egtra
|
---|
1123 | @date 2007/10/29
|
---|
1124 | @param[in, out] fmt
|
---|
1125 | @param[in] params
|
---|
1126 | @param[in, out] paramsCount
|
---|
1127 | @param[out] fieldWidth
|
---|
1128 | @param[in, out] flags
|
---|
1129 | */
|
---|
1130 | Sub ReadFieldWidth(ByRef fmt As *StrChar, params As *Object, ByRef paramsCount As SIZE_T,
|
---|
1131 | ByRef fieldWidth As DWord, ByRef flags As FormatFlags)
|
---|
1132 | Dim t As Long
|
---|
1133 | If ReadInt(fmt, params, paramsCount, t) Then
|
---|
1134 | If t < 0 Then
|
---|
1135 | flags Or= LeftSide
|
---|
1136 | fieldWidth = -t As DWord
|
---|
1137 | Else
|
---|
1138 | fieldWidth = t As DWord
|
---|
1139 | End If
|
---|
1140 | Else
|
---|
1141 | fieldWidth = 0
|
---|
1142 | End If
|
---|
1143 | End Sub
|
---|
1144 |
|
---|
1145 | /*!
|
---|
1146 | @brief 精度の読み込み
|
---|
1147 | @author Egtra
|
---|
1148 | @date 2007/10/29
|
---|
1149 | @param[in, out] fmt
|
---|
1150 | @param[in] params
|
---|
1151 | @param[in, out] paramsCount
|
---|
1152 | @return 読み取った精度。指定がなかったときには、DWORD_MAX。
|
---|
1153 | */
|
---|
1154 | Function ReadPrecision(ByRef fmt As *StrChar,
|
---|
1155 | params As *Object, ByRef paramsCount As SIZE_T) As DWord
|
---|
1156 |
|
---|
1157 | If fmt[0] = &h2e Then '.
|
---|
1158 | fmt = VarPtr(fmt[1]) 'po
|
---|
1159 | Dim t As Long
|
---|
1160 | ReadPrecision = 0
|
---|
1161 | If ReadInt(fmt, params, paramsCount, t) Then
|
---|
1162 | If t > 0 Then
|
---|
1163 | ReadPrecision = t As DWord
|
---|
1164 | End If
|
---|
1165 | End If
|
---|
1166 | Else
|
---|
1167 | ReadPrecision = DWORD_MAX
|
---|
1168 | End If
|
---|
1169 | End Function
|
---|
1170 |
|
---|
1171 | #ifdef _WIN64
|
---|
1172 | Const PtrLength = 1
|
---|
1173 | #else
|
---|
1174 | Const PtrLength = 0
|
---|
1175 | #endif
|
---|
1176 |
|
---|
1177 | /*!
|
---|
1178 | @biref 長さ指定の読み込み
|
---|
1179 | @author Egtra
|
---|
1180 | @date 2007/10/29
|
---|
1181 | @param[in, out] fmt
|
---|
1182 | @param[out] lengthSpec
|
---|
1183 | */
|
---|
1184 | Sub ReadLength(ByRef fmt As *StrChar, ByRef lengthSpec As Long)
|
---|
1185 | Do
|
---|
1186 | Select Case fmt[0]
|
---|
1187 | Case &h6c 'l
|
---|
1188 | lengthSpec++
|
---|
1189 | Case &h68 'h
|
---|
1190 | lengthSpec--
|
---|
1191 | Case &h6a 'j (u)intmax_t = QWord, Int64
|
---|
1192 | lengthSpec = 1
|
---|
1193 | Case &h74 't ptrdiff_t
|
---|
1194 | lengthSpec = PtrLength
|
---|
1195 | Case &h7a 'z (s)size_t
|
---|
1196 | lengthSpec = PtrLength
|
---|
1197 | Case &h70 'p VoidPtr 本来は変換指定子だが、ここで先読み
|
---|
1198 | lengthSpec = PtrLength
|
---|
1199 | Exit Sub 'fmtを進められると困るので、ここで脱出
|
---|
1200 | Case Else
|
---|
1201 | Exit Sub
|
---|
1202 | End Select
|
---|
1203 | fmt = VarPtr(fmt[1]) 'po
|
---|
1204 | Loop
|
---|
1205 | End Sub
|
---|
1206 |
|
---|
1207 | /*!
|
---|
1208 | @biref Cのsprintfのような書式文字列出力関数
|
---|
1209 | @author Egtra
|
---|
1210 | @date 2007/10/27
|
---|
1211 | @param[in] format 書式文字列。詳細は開発Wiki参照。
|
---|
1212 | @param[in, out] params 変換対象の配列。n = 0のときにはNULLも可。
|
---|
1213 | @param[in] n paramsの個数。
|
---|
1214 | @return 書式化された文字列。
|
---|
1215 | @todo %nへの対応
|
---|
1216 | */
|
---|
1217 | Function SPrintf(format As String, params As *Object, n As SIZE_T) As String
|
---|
1218 | Dim i = 0 As SIZE_T
|
---|
1219 | Dim paramsCount = 0 As SIZE_T
|
---|
1220 | Dim fmt = StrPtr(format)
|
---|
1221 | Dim s = New System.Text.StringBuilder
|
---|
1222 | Do
|
---|
1223 | Dim last = format.Length - (((fmt - StrPtr(format)) \ SizeOf (StrChar)) As LONG_PTR) As Long 'po
|
---|
1224 | Dim pos = ActiveBasic.Strings.ChrFind(fmt, last, &h25 As StrChar) As Long '&h25 = %
|
---|
1225 | If pos = -1 Then
|
---|
1226 | s.Append(fmt, 0, last)
|
---|
1227 | Exit Do
|
---|
1228 | End If
|
---|
1229 | '%以前の部分
|
---|
1230 | s.Append(fmt, 0, pos)
|
---|
1231 | fmt = VarPtr(fmt[pos + 1]) 'po
|
---|
1232 | 'フラグの読取
|
---|
1233 | Dim flags = None As FormatFlags
|
---|
1234 | If ReadFlags(fmt, flags) = False Then
|
---|
1235 | Exit Do
|
---|
1236 | End If
|
---|
1237 | 'フィールド幅
|
---|
1238 | Dim fieldWidth As DWord
|
---|
1239 | ReadFieldWidth(fmt, params, i, fieldWidth, flags)
|
---|
1240 | '精度
|
---|
1241 | Dim precision = ReadPrecision(fmt, params, i)
|
---|
1242 | '幅指定の読取
|
---|
1243 | Dim typeWidth As Long
|
---|
1244 | ReadLength(fmt, typeWidth)
|
---|
1245 |
|
---|
1246 | Select Case fmt[0]
|
---|
1247 | Case &h64 'd
|
---|
1248 | FormatInteger(s, TraitsIntegerD, params[i], True, typeWidth, precision, fieldWidth, flags)
|
---|
1249 | Case &h69 'i
|
---|
1250 | FormatInteger(s, TraitsIntegerD, params[i], True, typeWidth, precision, fieldWidth, flags)
|
---|
1251 | Case &h75 'u
|
---|
1252 | FormatInteger(s, TraitsIntegerU, params[i], False, typeWidth, precision, fieldWidth, flags)
|
---|
1253 | Case &h6f 'o
|
---|
1254 | FormatInteger(s, TraitsIntegerO, params[i], False, typeWidth, precision, fieldWidth, flags)
|
---|
1255 | Case &h4f 'O
|
---|
1256 | FormatInteger(s, TraitsIntegerO, params[i], False, typeWidth, precision, fieldWidth, flags Or Cap)
|
---|
1257 | Case &h78 'x
|
---|
1258 | FormatInteger(s, TraitsIntegerX, params[i], False, typeWidth, precision, fieldWidth, flags)
|
---|
1259 | Case &h58 'X
|
---|
1260 | FormatInteger(s, TraitsIntegerX, params[i], False, typeWidth, precision, fieldWidth, flags Or Cap)
|
---|
1261 | '現状ではVoidPtrを引数にする手段は無いはず
|
---|
1262 | ' Case &h58 'p
|
---|
1263 | ' FormatInteger(s, TraitsIntegerX, params[i], False, typeWidth, precision, fieldWidth, flags Or Cap)
|
---|
1264 | Case &h65 'e
|
---|
1265 | FormatFloat(s, AddressOf(FormatFloatE), params[i], precision, fieldWidth, flags)
|
---|
1266 | Case &h45 'E
|
---|
1267 | FormatFloat(s, AddressOf(FormatFloatE), params[i], precision, fieldWidth, flags Or Cap)
|
---|
1268 | Case &h66 'f
|
---|
1269 | FormatFloat(s, AddressOf(FormatFloatF), params[i], precision, fieldWidth, flags)
|
---|
1270 | Case &h46 'F
|
---|
1271 | FormatFloat(s, AddressOf(FormatFloatF), params[i], precision, fieldWidth, flags Or Cap)
|
---|
1272 | Case &h67 'g
|
---|
1273 | FormatFloat(s, AddressOf(FormatFloatG), params[i], precision, fieldWidth, flags)
|
---|
1274 | Case &h47 'G
|
---|
1275 | FormatFloat(s, AddressOf(FormatFloatG), params[i], precision, fieldWidth, flags Or Cap)
|
---|
1276 | Case &h61 'a
|
---|
1277 | FormatFloat(s, AddressOf(FormatFloatA), params[i], precision, fieldWidth, flags)
|
---|
1278 | Case &h41 'A
|
---|
1279 | FormatFloat(s, AddressOf(FormatFloatA), params[i], precision, fieldWidth, flags Or Cap)
|
---|
1280 | Case &h73 's
|
---|
1281 | s.Append(FormatString(params[i] As String, precision, fieldWidth, flags))
|
---|
1282 | Case &h63 'c
|
---|
1283 | s.Append(FormatCharacter(params[i] As BoxedStrChar, precision, fieldWidth, flags))
|
---|
1284 | ' Case &h6e 'n
|
---|
1285 | Case &h25 '%
|
---|
1286 | s.Append(&h25 As StrChar)
|
---|
1287 | i--
|
---|
1288 | Case 0
|
---|
1289 | Exit Do
|
---|
1290 | End Select
|
---|
1291 | fmt = VarPtr(fmt[1]) 'po
|
---|
1292 | i++
|
---|
1293 | Loop
|
---|
1294 | SPrintf = s.ToString
|
---|
1295 | End Function
|
---|
1296 |
|
---|
1297 | End Namespace 'Detail
|
---|
1298 |
|
---|
1299 | /*!
|
---|
1300 | @brief Cのsprintfのような書式化関数10引数版
|
---|
1301 | @author Egtra
|
---|
1302 | @date 2007/10/27
|
---|
1303 | @param[in] format 書式指定
|
---|
1304 | @param[in] paramN 引数
|
---|
1305 | @return 書式化された文字列
|
---|
1306 | */
|
---|
1307 |
|
---|
1308 | Function SPrintf(format As String, param0 As Object,
|
---|
1309 | param1 As Object, param2 As Object, param3 As Object,
|
---|
1310 | param4 As Object, param5 As Object, param6 As Object,
|
---|
1311 | param7 As Object, param8 As Object, param9 As Object) As String
|
---|
1312 |
|
---|
1313 | Dim params = VarPtr(param0) As *Object
|
---|
1314 |
|
---|
1315 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 10)
|
---|
1316 | End Function
|
---|
1317 |
|
---|
1318 | /*!
|
---|
1319 | @brief Cのsprintfのような書式化関数9引数版
|
---|
1320 | @author Egtra
|
---|
1321 | @date 2007/10/27
|
---|
1322 | @param[in] format 書式指定
|
---|
1323 | @param[in] paramN 引数
|
---|
1324 | @return 書式化された文字列
|
---|
1325 | */
|
---|
1326 | Function SPrintf(format As String, param0 As Object,
|
---|
1327 | param1 As Object, param2 As Object, param3 As Object,
|
---|
1328 | param4 As Object, param5 As Object, param6 As Object,
|
---|
1329 | param7 As Object, param8 As Object) As String
|
---|
1330 |
|
---|
1331 | Dim params = VarPtr(param0) As *Object
|
---|
1332 |
|
---|
1333 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 9)
|
---|
1334 | End Function
|
---|
1335 |
|
---|
1336 | /*!
|
---|
1337 | @brief Cのsprintfのような書式化関数8引数版
|
---|
1338 | @author Egtra
|
---|
1339 | @date 2007/10/27
|
---|
1340 | @param[in] format 書式指定
|
---|
1341 | @param[in] paramN 引数
|
---|
1342 | @return 書式化された文字列
|
---|
1343 | */
|
---|
1344 | Function SPrintf(format As String, param0 As Object,
|
---|
1345 | param1 As Object, param2 As Object, param3 As Object,
|
---|
1346 | param4 As Object, param5 As Object, param6 As Object,
|
---|
1347 | param7 As Object) As String
|
---|
1348 |
|
---|
1349 | Dim params = VarPtr(param0) As *Object
|
---|
1350 |
|
---|
1351 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 8)
|
---|
1352 | End Function
|
---|
1353 |
|
---|
1354 | /*!
|
---|
1355 | @brief Cのsprintfのような書式化関数7引数版
|
---|
1356 | @author Egtra
|
---|
1357 | @date 2007/10/27
|
---|
1358 | @param[in] format 書式指定
|
---|
1359 | @param[in] paramN 引数
|
---|
1360 | @return 書式化された文字列
|
---|
1361 | */
|
---|
1362 | Function SPrintf(format As String, param0 As Object,
|
---|
1363 | param1 As Object, param2 As Object, param3 As Object,
|
---|
1364 | param4 As Object, param5 As Object, param6 As Object) As String
|
---|
1365 |
|
---|
1366 | Dim params = VarPtr(param0) As *Object
|
---|
1367 |
|
---|
1368 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 7)
|
---|
1369 | End Function
|
---|
1370 |
|
---|
1371 | /*!
|
---|
1372 | @brief Cのsprintfのような書式化関数6引数版
|
---|
1373 | @author Egtra
|
---|
1374 | @date 2007/10/27
|
---|
1375 | @param[in] format 書式指定
|
---|
1376 | @param[in] paramN 引数
|
---|
1377 | @return 書式化された文字列
|
---|
1378 | */
|
---|
1379 | Function SPrintf(format As String, param0 As Object,
|
---|
1380 | param1 As Object, param2 As Object, param3 As Object,
|
---|
1381 | param4 As Object, param5 As Object) As String
|
---|
1382 |
|
---|
1383 | Dim params = VarPtr(param0) As *Object
|
---|
1384 |
|
---|
1385 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 6)
|
---|
1386 | End Function
|
---|
1387 |
|
---|
1388 | /*!
|
---|
1389 | @brief Cのsprintfのような書式化関数5引数版
|
---|
1390 | @author Egtra
|
---|
1391 | @date 2007/10/27
|
---|
1392 | @param[in] format 書式指定
|
---|
1393 | @param[in] paramN 引数
|
---|
1394 | @return 書式化された文字列
|
---|
1395 | */
|
---|
1396 | Function SPrintf(format As String, param0 As Object,
|
---|
1397 | param1 As Object, param2 As Object, param3 As Object,
|
---|
1398 | param4 As Object) As String
|
---|
1399 |
|
---|
1400 | Dim params = VarPtr(param0) As *Object
|
---|
1401 |
|
---|
1402 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 5)
|
---|
1403 | End Function
|
---|
1404 |
|
---|
1405 | /*!
|
---|
1406 | @brief Cのsprintfのような書式化関数4引数版
|
---|
1407 | @author Egtra
|
---|
1408 | @date 2007/10/27
|
---|
1409 | @param[in] format 書式指定
|
---|
1410 | @param[in] paramN 引数
|
---|
1411 | @return 書式化された文字列
|
---|
1412 | */
|
---|
1413 | Function SPrintf(format As String, param0 As Object,
|
---|
1414 | param1 As Object, param2 As Object, param3 As Object) As String
|
---|
1415 |
|
---|
1416 | Dim params = VarPtr(param0) As *Object
|
---|
1417 |
|
---|
1418 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 4)
|
---|
1419 | End Function
|
---|
1420 |
|
---|
1421 | /*!
|
---|
1422 | @brief Cのsprintfのような書式化関数3引数版
|
---|
1423 | @author Egtra
|
---|
1424 | @date 2007/10/27
|
---|
1425 | @param[in] format 書式指定
|
---|
1426 | @param[in] paramN 引数
|
---|
1427 | @return 書式化された文字列
|
---|
1428 | */
|
---|
1429 | Function SPrintf(format As String, param0 As Object,
|
---|
1430 | param1 As Object, param2 As Object) As String
|
---|
1431 |
|
---|
1432 | Dim params = VarPtr(param0) As *Object
|
---|
1433 |
|
---|
1434 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 3)
|
---|
1435 | End Function
|
---|
1436 |
|
---|
1437 | /*!
|
---|
1438 | @brief Cのsprintfのような書式化関数2引数版
|
---|
1439 | @author Egtra
|
---|
1440 | @date 2007/10/27
|
---|
1441 | @param[in] format 書式指定
|
---|
1442 | @param[in] paramN 引数
|
---|
1443 | @return 書式化された文字列
|
---|
1444 | */
|
---|
1445 | Function SPrintf(format As String, param0 As Object,
|
---|
1446 | param1 As Object) As String
|
---|
1447 |
|
---|
1448 | Dim params = VarPtr(param0) As *Object
|
---|
1449 |
|
---|
1450 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 2)
|
---|
1451 | End Function
|
---|
1452 |
|
---|
1453 | /*!
|
---|
1454 | @brief Cのsprintfのような書式化関数1引数版
|
---|
1455 | @author Egtra
|
---|
1456 | @date 2007/10/27
|
---|
1457 | @param[in] format 書式指定
|
---|
1458 | @param[in] paramN 引数
|
---|
1459 | @return 書式化された文字列
|
---|
1460 | */
|
---|
1461 | Function SPrintf(format As String, param0 As Object) As String
|
---|
1462 | Dim params = VarPtr(param0) As *Object
|
---|
1463 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 1)
|
---|
1464 | End Function
|
---|
1465 |
|
---|
1466 | /*!
|
---|
1467 | @brief Cのsprintfのような書式化関数0引数版
|
---|
1468 | @author Egtra
|
---|
1469 | @date 2007/10/27
|
---|
1470 | @param[in] format 書式指定
|
---|
1471 | @param[in] paramN 引数
|
---|
1472 | @return 書式化された文字列
|
---|
1473 | */
|
---|
1474 | Function SPrintf(format As String) As String
|
---|
1475 | SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, 0, 0)
|
---|
1476 | End Function
|
---|
1477 |
|
---|
1478 | End Namespace 'Strings
|
---|
1479 | End Namespace 'ActiveBasic
|
---|