# 標準ライブラリ
Volang 標準ライブラリは、テキストの加工、数学演算、その他の一般的な処理に必要な組み込み関数を幅広く提供します。これらの関数はすべてのスクリプトでグローバルに利用できます。
# 入力操作
このセクションでは、ロジックブロック内で入力データを読み取る関数について説明します。各ロジックブロックは 1 つ以上の入力チャネルを定義できます。入力値が変わると、そのブロックのスクリプトが実行されます。これらの関数を使うと、どの入力が実行をトリガーしたかを特定し、すべての入力の現在値を読み取れます。
# input::channel
現在のスクリプト実行をトリガーした入力チャネルの識別子を返します。ブロックに複数の入力がある場合、どの入力がブロックの実行原因かを判別するためにこの関数が必要になり、入力ごとに処理を分けられます。
パラメータ:
- なし。
戻り値:
- 実行をトリガーした入力の id を含む文字列。
例:
channel = input::channel()
if (channel == "input") {
// The main toggle input was triggered
...
} else if (channel == "on") {
// The dedicated "on" input was triggered
...
} else if (channel == "off") {
// The dedicated "off" input was triggered
...
}
# input::value
現在のスクリプト実行をトリガーした入力の値を返します。戻り値の型は、入力に定義された型 (boolean、number、string) によって決まります。input::channel() と組み合わせて、どの入力が変わったかと新しい値の両方を特定します。
パラメータ:
- なし。
戻り値:
- トリガーとなった入力の現在値。型は入力定義 (boolean、number、string) によって決まります。
例:
channel = input::channel()
value = input::value()
// React to a rising edge on a boolean input
if (channel == "input" and value) {
output::toggle("output")
}
# input::get
識別子を指定して、特定の入力の最後に知られている値を取得します。input::value() が現在の実行をトリガーした入力の値だけを返すのに対し、この関数はいつでも任意の入力に保存された値を読み取れます。
パラメータ:
id(string): 読み取る入力の識別子。
戻り値:
- 指定した入力の最後に知られている値。型は入力定義 (boolean、number、string) によって決まります。
例:
// Read the current temperature from an input
current_temp = input::get("value")
// Use the value in control logic
if (current_temp > 25.0) {
output::set("cooling", true)
}
# 出力操作
このセクションでは、ロジックブロックの出力を制御する関数について説明します。各ブロックは 1 つ以上の出力を定義でき、値を他の接続されたブロックへ伝播できます。
# output::get
識別子を指定して、特定の出力の現在値を取得します。変更する前に出力の現在状態を読み取るのに便利です。
パラメータ:
id(string): 読み取る出力の識別子。
戻り値:
- 指定した出力の現在値。型は出力定義 (boolean、number、string) によって決まります。
例:
// Check the current output state before toggling
prev = output::get("output")
if (prev) {
std::print("Output is currently ON, turning OFF")
}
output::set("output", !prev)
# output::set
識別子を指定して、特定の出力の値を設定します。値の型は、その出力に定義された型 (boolean、number、string) と一致している必要があります。出力を設定すると、新しい値が接続されたブロックへ伝播します。
パラメータ:
id(string): 設定する出力の識別子。value: 代入する新しい値。出力に定義された型と一致している必要があります。
戻り値:
- なし。
例:
// Set a boolean output
output::set("output", true)
// Set a numeric output based on calculation
midpoint = config::get("midpoint")
hysteresis = config::get("hysteresis")
value = input::get("value")
if (value >= midpoint + hysteresis) {
output::set("output", true)
} else if (value <= midpoint - hysteresis) {
output::set("output", false)
}
# output::toggle
boolean 型の出力をトグルし、現在値を反転します。出力が現在 true なら false になり、その逆も同様です。この関数は boolean 型の出力でのみ動作します。
パラメータ:
id(string): トグルする boolean 型出力の識別子。
戻り値:
- なし。
例:
channel = input::channel()
value = input::value()
// Toggle the output on a rising edge of the input
if (channel == "input") {
last_state = state::get("last_input_state")
if (value and !last_state) {
output::toggle("output")
}
state::set("last_input_state", value)
}
# 状態操作
このセクションでは、ロジックブロック内の永続状態を管理する関数について説明します。状態変数はスクリプト実行の間も値を保持するため、エッジ検出、カウンタ、タイミング情報など、時間経過に伴う条件の追跡に欠かせません。利用可能な状態変数とその型はブロック記述子で定義されます。
# state::get
識別子を指定して、永続状態変数の現在値を取得します。
パラメータ:
id(string): 読み取る状態変数の識別子。
戻り値:
- 状態変数の現在値。型は状態変数定義 (boolean、number、string、array) によって決まります。
array 型の状態変数では、返されるハンドルはコピーではなく、状態に保存された配列を指します。そのハンドル経由での変更 (array::append や array::clear など) は状態を直接更新するため、後から state::set を呼ぶ必要はありません。array 型の状態変数は常に空の配列から始まります。
例:
// Use state to detect a rising edge (transition from false to true)
value = input::value()
last_state = state::get("last_input_state")
if (value and !last_state) {
// Rising edge detected - take action
output::toggle("output")
}
state::set("last_input_state", value)
# state::set
識別子を指定して、永続状態変数に値を保存します。値はスクリプト実行の間も保持されるため、ブロックは複数の入力イベントにまたがって情報を記憶できます。値の型は、その状態変数に定義された型と一致している必要があります。
パラメータ:
id(string): 更新する状態変数の識別子。value: 保存する新しい値。状態変数に定義された型 (boolean、number、string、array) と一致している必要があります。
保存する値が array の場合、状態はコピーではなく参照を保持します。呼び出し後もスクリプトはハンドル経由で配列を変更でき、次に状態を読むと変更が反映されています。state::get はすでに保存された配列への共有ハンドルを返すため、別の配列に置き換えるときだけ state::set が必要です。
戻り値:
- なし。
例:
// Track the timestamp of the last input change
channel = input::channel()
value = input::value()
if (channel == "input") {
state::set("last_change_time", time::now())
// Calculate how long the input was in its previous state
elapsed = time::now() - state::get("last_change_time")
if (elapsed > 60) {
std::print("Input was stable for over a minute")
}
}
# 設定操作
このセクションでは、ブロックの設定パラメータを読み取る関数について説明します。設定値は Voldeno Studio でユーザーが設定し、スクリプト内からは読み取り専用です。コードを変更せずにブロックをカスタマイズできます。たとえば、しきい値、遅延、動作モードの設定などです。
# config::get
識別子を指定して、設定パラメータの値を取得します。設定パラメータはブロック記述子で定義され、値は Voldeno Studio でユーザーが設定します。スクリプトからは読み取りのみ可能で、変更はできません。
パラメータ:
id(string): 読み取る設定パラメータの識別子。
戻り値:
- 設定パラメータの値。型はパラメータ定義 (number、string、enum) によって決まります。enum 型パラメータは 0 始まりの数値インデックスを返します。
例:
// Read delay configuration in milliseconds
delay_on_ms = config::get("delay_on_ms")
delay_off_ms = config::get("delay_off_ms")
// Use an enum config to select behavior mode
mode = config::get("mode") // Returns 0, 1, 2... based on selected option
if (mode == 0) {
// First mode logic
...
} else if (mode == 1) {
// Second mode logic
...
}
// Read a numeric threshold from config
scale = config::get("scale")
offset = config::get("offset")
result = input::value() * scale + offset
output::set("value", result)
# 非同期操作
このセクションでは、関数呼び出しを遅延実行するための関数について説明します。Volang は非ブロッキング言語で、sleep 関数は提供されません。代わりにコールバックを使い、指定した遅延後にユーザー定義関数を呼び出すことで、時間ベースのロジックを実現します。
遅延、時間指定パルス、モーター制御シーケンス、一定時間経過後に動作するロジックなどの実装に欠かせません。コールバックは呼び出し先関数へ引数を渡せ、関数側からさらにコールバックをスケジュールして多段階のシーケンスを作れます。
ブロックごとに同時に有効にできるコールバックは 1 つだけです。保留中のコールバックがある状態で新しいコールバックをスケジュールするには、先に callback::clear() で既存のものを解除する必要があります。
# callback::set
指定した遅延 (ミリ秒) 後に、ユーザー定義の extern 関数への遅延呼び出しをスケジュールします。関数は文字列の名前で指定します。追加引数を渡すと、コールバック関数のパラメータとして受け渡されます。
対象関数はスクリプト内で extern fn 構文で宣言する必要があります。遅延が経過すると、システムは指定された引数でその関数を呼び出します。
パラメータ:
delay_ms(integer): 関数が呼び出されるまでの遅延 (ミリ秒)。function_name(string): 呼び出すextern fnの名前。...args(optional): コールバック関数へ渡す追加引数。任意の型の値を 0 個以上渡せます。
戻り値:
- なし。
例:
// Define a simple callback handler
extern fn onTimeout() {
output::set("output", true)
}
// Schedule the callback to fire after a configurable delay
delay_ms = config::get("delay_ms")
callback::set(delay_ms, "onTimeout")
例 (引数を渡す場合):
// Callback that chains into the next step
extern fn onSequence(step) {
if (step == 1) {
output::set("output", true)
// Schedule step 2 after a pulse duration
pulse_ms = config::get("pulse_ms")
callback::set(pulse_ms, "onSequence", 2)
return
}
if (step == 2) {
output::set("output", false)
return
}
}
// Start the sequence after an initial delay
callback::set(1000, "onSequence", 1)
# callback::clear
ブロックに現在スケジュールされているコールバックをすべてキャンセルします。新しいコールバックをスケジュールする前、または保留中の処理が不要になったとき (たとえば、遅延が切れる前に入力が変わった場合) に呼び出します。
パラメータ:
- なし。
戻り値:
- なし。
例:
extern fn onCallback(value) {
if (value == 1) {
output::set("output", true)
} else if (value == 2) {
output::set("output", false)
}
}
channel = input::channel()
value = input::value()
if (channel == "input") {
last = state::get("last_input_state")
if (value != last) {
state::set("last_input_state", value)
// Always clear the previous callback before scheduling a new one
callback::clear()
if (value) {
delay_ms = config::get("delay_on_ms")
if (delay_ms > 0) {
callback::set(delay_ms, "onCallback", 1)
} else {
output::set("output", true)
}
} else {
delay_ms = config::get("delay_off_ms")
if (delay_ms > 0) {
callback::set(delay_ms, "onCallback", 2)
} else {
output::set("output", false)
}
}
}
}
# 文字列操作
このセクションでは、文字列を操作する関数について説明します。
# str::len
指定した文字列の文字数を計算します。
パラメータ:
text(string): 計測対象の入力文字列。
戻り値:
- 文字列内の文字数を表す整数値。
例:
// Check if the user PIN code has the required length
user_pin = "1234"
if (str::len(user_pin) == 4) {
...
}
# str::trim
文字列の先頭と末尾にある空白文字 (スペース、タブ、改行) をすべて削除します。外部システムから受け取ったコマンドの解析や、余分な空白が混ざるユーザー入力の整理に欠かせません。
パラメータ:
text(string): トリム対象の入力文字列。
戻り値:
- 前後の空白を除いた新しい文字列。
例:
// Clean up a command received from an external module
input = " START "
command = str::trim(input)
// Now the string is "START" and can be compared safely
if (command == "START") {
....
}
# str::concat
2 つ以上の文字列を連結して 1 つの文字列にします。この関数は可変長引数で、任意個の引数を受け取れるため、複雑なメッセージやコマンドを動的に組み立てられます。
パラメータ:
...strings: 連結する文字列引数の列。必要な数だけカンマ区切りで渡せます。引数が 1 つだけの場合は、その引数自体を返します。
戻り値:
- すべての入力文字列を順に連結した新しい文字列。
例:
room = "Living Room"
temp = "22.5"
// Construct a full status message using multiple arguments
message = str::concat("Status: ", room, " is currently ", temp, "°C")
// Result: "Status: Living Room is currently 22.5°C"
# str::count
文字列内で部分文字列が重ならずに出現する回数を数えます。start と end 引数で、文字列内の特定範囲に検索を限定することもできます。
パラメータ:
text(string): 検索対象の文字列。substring(string): 出現回数を数える部分文字列。start(integer, optional): 検索を開始する位置。既定値は0。end(integer, optional): 検索を終了する位置 (この位置は含まない)。既定値は文字列の末尾。
戻り値:
- 部分文字列の重ならない出現回数を表す整数値。
例:
// Count all occurrences of a word
text = "I love apples, apple are my favorite fruit"
count = str::count(text, "apple") // Returns 2
// Count occurrences within a range
data = "abcabcabc"
count = str::count(data, "abc", 1) // Returns 2 (skips first "abc")
count = str::count(data, "abc", 1, 7) // Returns 1
// Empty substring returns length + 1
count = str::count("hello", "") // Returns 6
// Non-overlapping: "aaaa" contains 2 non-overlapping "aa"
count = str::count("aaaa", "aa") // Returns 2
# str::replace
文字列内の部分文字列を新しい部分文字列に置き換えます。既定ではすべての出現箇所を置き換えます。オプションの count パラメータで、左から右への置換回数を制限できます。
パラメータ:
text(string): 元の文字列。old(string): 置き換え対象の部分文字列。new(string): 置き換え後の部分文字列。count(integer, optional): 最大置換回数。省略するとすべての出現箇所を置き換えます。
戻り値:
- 置換を適用した新しい文字列。
例:
// Replace all occurrences
result = str::replace("one one was a horse", "one", "three")
// Returns "three three was a horse"
// Replace only the first occurrence
result = str::replace("one one was a horse", "one", "three", 1)
// Returns "three one was a horse"
// Delete by replacing with empty string
result = str::replace("hello", "l", "") // Returns "heo"
// Empty old string inserts between every character
result = str::replace("abc", "", "-") // Returns "-a-b-c-"
# str::number
文字列引数を解析して数値に変換します。文字列に小数点が含まれる場合は float、そうでなければ integer を返します。形式は自動判定されます。
パラメータ:
text: 数値表現を含む文字列。
戻り値:
- 入力形式に応じた整数または float の数値。
例:
// Case 1: Parsing an integer (e.g., brightness level)
brightness = str::number("80") // Returns Integer 80
// Case 2: Parsing a float (e.g., temperature)
temp_str = "21.5"
threshold = str::number(temp_str) // Returns Float 21.5
current_temp = 22
// Using the converted value in logic
if (current_temp > threshold) {
...
}
# str::fmt
テンプレート文字列内の {} プレースホルダーを、渡された引数の文字列表現で置き換えて書式付き文字列を組み立てます。異なる型 (string、数値、boolean) の可変個引数を受け取り、挿入前に自動で文字列へ変換します。置換は位置順です。1 番目の {} は 1 番目の引数、2 番目の {} は 2 番目の引数、という順序になります。
パラメータ:
template: 波括弧{}プレースホルダーを含む書式文字列。...args: プレースホルダーへ代入する値の列。数値、文字列、boolean リテラル (true/false) などに対応します。
戻り値:
- すべてのプレースホルダーを対応する値で置き換えた新しい文字列。
例:
sensorName = "Kitchen_Main"
temp = 22.5
isActive = true
// Format a complex log message without manual concatenation
log = str::fmt("Sensor {} status: Active={}, Value={}°C", sensorName, isActive, temp)
// Result: "Sensor Kitchen_Main status: Active=true, Value=22.5°C"
# str::split
文字列分割操作を初期化し、イテレータ状態を作成します。この関数はすぐに分割を実行しません。代わりに、現在位置と文字列走査に必要なロジックを保持する不透明な handle オブジェクトを返します。実際の部分文字列を 1 つずつ取得するには、このオブジェクトを str::split_next または str::split_has_next に渡します。
パラメータ:
text: 分割対象の元文字列。separator: チャンク間の境界を示す区切り文字列。
戻り値:
- 進行中の分割セッションを表す不透明なハンドル。このオブジェクトを直接変更しないでください。
例:
rawData = "sensor1;25.5;active"
// Initialize the splitter. 'iterator' now holds the state.
iterator = str::split(rawData, ";")
// The iterator is now ready to be consumed by split_next...
# str::split_has_next
現在の分割セッションから取得できる部分文字列がまだあるかを確認します。str::split が作成した不透明な state オブジェクトを調べます。状態を変更したりイテレータ位置を進めたりはせず、利用可否だけを確認します。文字列の各部分を走査する while ループの条件としてよく使われます。
パラメータ:
state:str::splitが返す不透明なハンドル。
戻り値:
- 取得可能な部分文字列が 1 つ以上あれば
true、そうでなければfalseを返します。
例:
data = "RED,GREEN,BLUE"
iterator = str::split(data, ",")
// Loop as long as there are tokens left
while (str::split_has_next(iterator)) {
...
// Safe to call split_next() here
// color = str::split_next(iterator)
}
# str::split_next
分割シーケンスから次の部分文字列を取り出して返し、イテレータを次の位置へ進めます。不透明な state が指す文字列の現在セグメントを消費します。文字列のすべての部分を処理するまで、順に呼び出す想定です。
パラメータ:
state:str::splitが返す不透明なハンドル。
戻り値:
- 元の文字列の次のセグメント。
注意: 安全に反復するには、この関数を呼ぶ前に
str::split_has_next(state)で取得可能か確認することを推奨します。
例:
// Scenario: Parsing a command string "SET_COLOR;255;0;0"
commandRaw = "SET_COLOR;255;0;0"
iter = str::split(commandRaw, ";")
// We know the format, so we can extract parts manually
if (str::split_has_next(iter)) {
cmd = str::split_next(iter) // "SET_COLOR"
r = str::split_next(iter) // "255"
g = str::split_next(iter) // "0"
b = str::split_next(iter) // "0"
...
}
# 配列操作
このセクションでは、配列を作成・操作する関数について説明します。
# array::new
渡された値で初期化した新しい配列を作成します。この関数は可変長引数で、任意の型の値を任意個受け取れます。引数なしで呼ぶと空の配列を作成します。配列は混合型を保持でき、他の配列関数でサイズを動的に変更できます。
パラメータ:
...values(optional): 配列を初期化する値の列。任意の型 (数値、文字列、boolean、その他の配列) の引数を 0 個以上渡せます。引数がなければ空の配列を作成します。
戻り値:
- 作成された配列を表す不透明なハンドル。配列内容を操作するには、
array::put_at、array::get_at、array::lenなどの他の配列関数へ渡します。
例:
// Create an empty array
empty = array::new()
// Create an array with initial numeric values
temperatures = array::new(21.5, 22.0, 19.8, 23.1)
// Create an array with mixed types
config = array::new("sensor1", 100, true)
// Create an array with string values for room names
rooms = array::new("Living Room", "Kitchen", "Bedroom", "Bathroom")
// Arrays can be used to collect sensor readings over time
readings = array::new()
// Later: array::push(readings, current_value)
# array::len
配列に現在格納されている要素数を返します。配列が空かどうかの確認、全要素の走査、特定インデックスへアクセスする前のサイズ検証に便利です。
パラメータ:
arr:array::newが返す不透明な配列ハンドル。
戻り値:
- 配列内の要素数を表す整数値。
例:
// Check the size of an array
temps = array::new(21.5, 22.0, 19.8)
count = array::len(temps) // Returns 3
// Check if an array is empty
data = array::new()
if (array::len(data) == 0) {
std::print("No data collected yet")
}
// Use length for iteration bounds
sensors = array::new("temp1", "temp2", "humidity")
i = 0
while (i < array::len(sensors)) {
// Process each sensor...
i = i + 1
}
# array::get_at
配列の指定インデックスに格納されている値を取得します。配列インデックスは 0 始まりで、最初の要素はインデックス 0、2 番目は 1、という順序です。
パラメータ:
arr:array::newが返す不透明な配列ハンドル。index: 取得する要素の 0 始まり位置。
戻り値:
- 指定インデックスに格納されている値。戻り値の型はその位置に保存された値によって決まります。
警告: この関数を呼ぶ前に、インデックスが有効範囲内 (
0 <= index < array::len(arr)) であることを確認してください。存在しないインデックスへアクセスすると プログラム実行エラー となり、未定義の動作につながる可能性があります。必ず先にarray::len()でインデックスを検証してください。
例:
temps = array::new(21.5, 22.0, 19.8, 23.1)
// Safe access: check bounds first
index = 2
if (index < array::len(temps)) {
value = array::get_at(temps, index) // Returns 19.8
std::print(str::fmt("Temperature at index {}: {}°C", index, value))
}
// Iterate safely over all elements
i = 0
while (i < array::len(temps)) {
temp = array::get_at(temps, i)
if (temp > 22.0) {
std::print(str::fmt("High temperature detected: {}°C", temp))
}
i = i + 1
}
// DANGEROUS: Never do this without bounds checking!
// value = array::get_at(temps, 10) // Undefined behavior - may crash!
# array::put_at
配列の指定インデックスに値を保存し、その位置の既存値を置き換えます。配列インデックスは 0 始まりで、最初の要素はインデックス 0、2 番目は 1、という順序です。この関数は配列をその場で変更し、戻り値はありません。
パラメータ:
arr:array::newが返す不透明な配列ハンドル。index: 値を保存する 0 始まり位置。value: 指定インデックスに保存する値。値の型は、その位置にすでに格納されている要素の型と一致している必要があります。
戻り値:
- なし。
警告: この関数を呼ぶ前に、インデックスが有効範囲内 (
0 <= index < array::len(arr)) であることを確認してください。存在しないインデックスへ書き込もうとすると プログラム実行エラー となり、未定義の動作につながる可能性があります。必ず先にarray::len()でインデックスを検証してください。
例:
// Create an array with initial values
temps = array::new(21.5, 22.0, 19.8, 23.1)
// Safe update: check bounds first
index = 1
if (index < array::len(temps)) {
array::put_at(temps, index, 25.0) // Replace 22.0 with 25.0
}
// Update all values in a loop
i = 0
while (i < array::len(temps)) {
current = array::get_at(temps, i)
// Apply a correction factor
array::put_at(temps, i, current + 0.5)
i = i + 1
}
// Update specific elements in an array of strings
sensors = array::new("sensor1", "sensor2", "sensor3")
array::put_at(sensors, 0, "temp1")
array::put_at(sensors, 1, "temp2")
array::put_at(sensors, 2, "humidity")
// DANGEROUS: Never do this without bounds checking!
// array::put_at(temps, 10, 99.9) // Undefined behavior - may crash!
# array::append
配列の末尾に値を追加し、サイズを 1 増やします。最終サイズが事前に分からない場合に、配列を動的に組み立てるのに便利です。
パラメータ:
arr:array::newが返す不透明な配列ハンドル。value: 配列末尾に追加する値。
戻り値:
- なし。
例:
// Build an array dynamically by appending values
temps = array::new(21.5)
array::append(temps, 22.0)
array::append(temps, 19.8)
array::append(temps, 23.1)
// temps now contains: [21.5, 22.0, 19.8, 23.1]
// Collect sensor readings over time
readings = array::new(0.0) // Initialize with first reading
array::append(readings, 0.5)
array::append(readings, 1.2)
// Check the new size
count = array::len(readings) // Returns 3
// Append in a loop (e.g., collecting 5 readings)
data = array::new(100)
i = 0
while (i < 4) {
array::append(data, 100 + i)
i = i + 1
}
// data now contains: [100, 100, 101, 102, 103]
# array::clear
配列からすべての要素を削除し、空にします。この関数を呼んだ後、array::len(arr) は 0 を返します。新しい配列を作らずに既存の配列を再利用するのに便利です。
パラメータ:
arr:array::newが返す不透明な配列ハンドル。
戻り値:
- なし。
例:
// Create and populate an array
temps = array::new(21.5, 22.0, 19.8, 23.1)
std::print(str::fmt("Length before clear: {}", array::len(temps))) // 4
// Clear all elements
array::clear(temps)
std::print(str::fmt("Length after clear: {}", array::len(temps))) // 0
// The array can be reused
array::append(temps, 25.0)
array::append(temps, 26.5)
// temps now contains: [25.0, 26.5]
// Useful for periodic data collection - clear old readings
readings = array::new(0.0)
// ... collect readings ...
array::append(readings, 1.5)
array::append(readings, 2.3)
// ... process readings ...
// Reset for next collection cycle
array::clear(readings)
# マップ操作
このセクションでは、マップ (キーと値の辞書) を作成・操作する関数について説明します。Volang のマップは文字列をキーに使い、任意の型の値を格納できます。
# map::new
新しい空のマップを作成します。マップはキーが常に文字列であるキーと値のペアの集合です。値は任意の型 (数値、文字列、boolean、配列、その他のマップ) にできます。構造化データ、設定、JSON に似たオブジェクトの表現の保存に便利です。
パラメータ:
- なし。
戻り値:
- 作成されたマップを表す不透明なハンドル。マップ内容を操作するには、
map::set、map::get、map::containsなどの他のマップ関数へ渡します。
例:
// Create an empty map
config = map::new()
// The map is now ready to store key-value pairs
// map::set(config, "temperature", 22.5)
// map::set(config, "location", "Living Room")
// Maps are also returned by some functions, e.g., HTTP response headers
// In http::on_response callback, 'headers' parameter is a map
# map::len
マップに現在格納されているキーと値のペア数を返します。マップが空かどうか、エントリ数を確認するのに便利です。
パラメータ:
map:map::newが返す不透明なマップハンドル。
戻り値:
- マップ内のキーと値のペア数を表す整数値。
例:
config = map::new()
// Check the size of an empty map
count = map::len(config) // Returns 0
// After adding elements, the count increases
// map::set(config, "temperature", 22.5)
// map::set(config, "humidity", 45)
// count = map::len(config) // Returns 2
// Check if a map is empty
if (map::len(config) == 0) {
std::print("Map is empty")
}
# map::set
マップ内の指定キーに対する値を追加または更新します。キーが存在しない場合は新しいキーと値のペアを作成します。キーがすでに存在する場合は値を置き換えますが、新しい値は既存値と同じ型である必要があります。
パラメータ:
map:map::newが返す不透明なマップハンドル。key: キー名を指定する文字列。value: 保存する値。任意の型 (number、string、boolean、array、その他のマップ) にできます。
戻り値:
- なし。
例:
config = map::new()
// Add new key-value pairs
map::set(config, "temperature", 22.5)
map::set(config, "location", "Living Room")
map::set(config, "active", true)
// Update existing value (same type required)
map::set(config, "temperature", 23.0) // OK - float to float
// Store different types under different keys
map::set(config, "sensor_count", 5) // integer
map::set(config, "sensor_name", "temp1") // string
map::set(config, "enabled", true) // boolean
# map::get
マップから指定キーに関連付けられた値を取得します。戻り値の型は、そのキーに保存された値によって決まります。
パラメータ:
map:map::newが返す不透明なマップハンドル。key: 取得するキー名を指定する文字列。
戻り値:
- 指定キーに格納されている値。戻り値の型は保存された値の型と一致します。
警告: 指定キーはマップ内に存在している必要があります。存在しないキーの値を取得しようとすると ランタイムエラー になります。この関数を呼ぶ前に、必ず
map::containsでキーの存在を確認してください。
例:
config = map::new()
map::set(config, "temperature", 22.5)
map::set(config, "location", "Living Room")
// Safe access: check if key exists first
if (map::contains(config, "temperature")) {
temp = map::get(config, "temperature")
std::print(str::fmt("Temperature: {}°C", temp))
}
// Access value when you know the key exists
location = map::get(config, "location") // Returns "Living Room"
// DANGEROUS: Never do this without checking first!
// value = map::get(config, "nonexistent") // Runtime error!
# map::clear
マップからすべてのキーと値のペアを削除し、空にします。この関数を呼んだ後、map::len(map) は 0 を返します。新しいマップを作らずに既存のマップを再利用するのに便利です。
パラメータ:
map:map::newが返す不透明なマップハンドル。
戻り値:
- なし。
例:
config = map::new()
map::set(config, "temperature", 22.5)
map::set(config, "humidity", 45)
std::print(str::fmt("Size before clear: {}", map::len(config))) // 2
// Clear all entries
map::clear(config)
std::print(str::fmt("Size after clear: {}", map::len(config))) // 0
// The map can be reused
map::set(config, "new_key", "new_value")
# map::contains
指定キーがマップ内に存在するかを確認します。存在しないキーへアクセスしてランタイムエラーになるのを防ぐため、map::get を呼ぶ前に使います。
パラメータ:
map:map::newが返す不透明なマップハンドル。key: A string specifying the key name to check.
戻り値:
- キーがマップ内に存在すれば
true、そうでなければfalseを返します。
例:
config = map::new()
map::set(config, "temperature", 22.5)
map::set(config, "location", "Living Room")
// Check if a key exists
if (map::contains(config, "temperature")) {
std::print("Temperature key exists")
temp = map::get(config, "temperature")
}
// Check for non-existent key
if (map::contains(config, "humidity")) {
humidity = map::get(config, "humidity")
} else {
std::print("Humidity not set")
}
// Use in conditional logic
key = "location"
if (map::contains(config, key)) {
value = map::get(config, key)
std::print(str::fmt("Found {}: {}", key, value))
}
# map::keys
マップに現在格納されているすべてのキーを含む配列を返します。返された配列は array::len と array::get_at で走査し、各キーを処理できます。キーの順序は保証されません。
パラメータ:
map:map::newが返す不透明なマップハンドル。
戻り値:
- 各要素がマップのキーである文字列の配列。
例:
settings = map::new()
map::set(settings, "brightness", 80)
map::set(settings, "color", "warm")
map::set(settings, "enabled", true)
keys = map::keys(settings)
i = 0
while (i < array::len(keys)) {
key = array::get_at(keys, i)
value = map::get(settings, key)
std::print(str::fmt("{} = {}", key, value))
i = i + 1
}
# map::values
マップに現在格納されているすべての値を含む配列を返します。返された配列は array::len と array::get_at で走査できます。値の順序は map::keys が返すキーの順序に対応します。
パラメータ:
map:map::newが返す不透明なマップハンドル。
戻り値:
- 各要素がマップの値である配列。要素は任意の型にできます。
例:
sensors = map::new()
map::set(sensors, "temp", 22.5)
map::set(sensors, "humidity", 65)
values = map::values(sensors)
i = 0
while (i < array::len(values)) {
std::print(array::get_at(values, i))
i = i + 1
}
# JSON 操作
このセクションでは、JSON データを扱う関数について説明します。JSON (JavaScript Object Notation) は、特に Web API との通信でよく使われるデータ交換形式です。
# json::get
ドット記法のパスを使って JSON 文字列から値を取り出します。この関数は JSON を解析し、ネストしたオブジェクトをたどって指定位置の値を取得します。
パラメータ:
json: 有効な JSON データを含む文字列。path: ドット記法で目的のフィールドへのパスを指定する文字列 (例:"a.b.c.d")。
戻り値:
- 指定パスにある値。戻り値の型は JSON 値の型 (
string、number、bool、array) によって決まります。arrayは配列操作で説明したのと同じ配列型で、array::*関数で利用できます。
例:
// Simple JSON object
json_data = """{"temperature": 22.5, "location": "Living Room", "active": true}"""
temp = json::get(json_data, "temperature") // Returns 22.5
location = json::get(json_data, "location") // Returns "Living Room"
active = json::get(json_data, "active") // Returns true
// Nested JSON object
nested = """{"sensor": {"id": "temp1", "value": 23.5, "enabled": false}}"""
sensor_id = json::get(nested, "sensor.id") // Returns "temp1"
sensor_value = json::get(nested, "sensor.value") // Returns 23.5
sensor_enabled = json::get(nested, "sensor.enabled") // Returns false
// Deeply nested structure
deep = """{"building": {"floor": {"room": {"temperature": 22.0}}}}"""
room_temp = json::get(deep, "building.floor.room.temperature") // Returns 22.0
// Getting an array value
json_with_array = """{"readings": [21.5, 22.0, 22.5]}"""
readings = json::get(json_with_array, "readings") // Returns array [21.5, 22.0, 22.5]
# HTTP 操作
このセクションでは、外部サービスへ HTTP リクエストを送る関数について説明します。Volang スクリプトから Web API と通信したり、通知を送ったり、サードパーティサービスと連携したりできます。
# http::client
HTTP リクエストに必要な新しい HTTP クライアント インスタンスを作成します。クライアントは接続設定を管理し、リクエスト実行を担当します。他の HTTP 関数を呼ぶ前に作成する必要があります。
パラメータ:
- なし。
戻り値:
- HTTP クライアントを表す不透明なハンドル。リクエストを実行するには、
http::callなどの他の HTTP 関数へ渡します。
例:
// Create an HTTP client
client = http::client()
// The client is now ready to make requests
# http::set_method
リクエストの HTTP メソッドを設定します。http::call でリクエストを実行する前に呼ぶ必要があります。設定しない場合、既定のメソッドは GET です。
パラメータ:
client:http::clientが返す不透明な HTTP クライアント ハンドル。method: HTTP メソッドを指定する文字列。対応値:"GET"、"POST"、"PUT"、"DELETE"、"PATCH"、"HEAD"、"OPTIONS"。
戻り値:
- なし。
例:
client = http::client()
// Set method to POST for sending data
http::set_method(client, "POST")
// Set method to GET for retrieving data (this is the default)
http::set_method(client, "GET")
// Set method to PUT for updating resources
http::set_method(client, "PUT")
// Set method to DELETE for removing resources
http::set_method(client, "DELETE")
# http::set_header
リクエストにカスタム HTTP ヘッダーを追加します。複数回呼び出して複数のヘッダーを追加できます。ヘッダーは認証トークン、Content-Type、カスタム メタデータなど、リクエストに付加情報を渡すために使います。
パラメータ:
client:http::clientが返す不透明な HTTP クライアント ハンドル。key: ヘッダー名を指定する文字列 (例:"Content-Type"、"Authorization")。value: ヘッダー値を指定する文字列。
戻り値:
- なし。
例:
client = http::client()
http::set_method(client, "POST")
// Set content type for JSON data
http::set_header(client, "Content-Type", "application/json")
// Add authorization header with API key
http::set_header(client, "Authorization", "Bearer my-api-token-123")
// Add custom headers
http::set_header(client, "X-Custom-Header", "custom-value")
http::set_header(client, "Accept", "application/json")
# http::set_body
リクエスト本文の内容を設定します。通常、POST、PUT、PATCH リクエストでサーバーへデータを送るときに使います。本文には JSON、フォーム データ、その他のテキスト形式を含められます。本文形式に合わせて、http::set_header で適切な Content-Type ヘッダーを設定してください。
パラメータ:
client:http::clientが返す不透明な HTTP クライアント ハンドル。body: リクエスト本文を含む文字列。
戻り値:
- なし。
例:
client = http::client()
http::set_method(client, "POST")
http::set_header(client, "Content-Type", "application/json")
// Set JSON body
http::set_body(client, """{"temperature": 22.5, "humidity": 45}""")
// Or build the body dynamically using str::fmt
temp = 22.5
humidity = 45
body = str::fmt("""{"temperature": {}, "humidity": {}}""", temp, humidity)
http::set_body(client, body)
# http::call
設定済みのクライアント設定 (メソッド、ヘッダー、本文) を使って、指定 URL へ HTTP リクエストを実行します。この関数は非同期で、リクエストを送ってすぐに戻ります。応答は http::on_response コールバック関数経由で届き、スクリプト内で定義する必要があります。対応プロトコルは http:// と https:// です。
パラメータ:
client:http::clientが返す不透明な HTTP クライアント ハンドル。url: リクエスト送信先の完全な URL を含む文字列。
戻り値:
- なし。応答は
http::on_responseコールバック経由で非同期に届きます。
コールバック: http::on_response(status, body, headers)
HTTP 応答を受け取るには、次のシグネチャで外部コールバック関数を定義する必要があります:
extern fn http::on_response(status, body, headers) {
// Handle the response here
}
コールバック パラメータ:
status: HTTP ステータス コードを表す整数 (例: 成功は200、見つからない場合は404、サーバー エラーは500)。body: 応答本文を含む文字列。headers: 応答ヘッダーをキーと値のペアとして含むマップ オブジェクト (マップ操作を参照)。
例:
// Define the response callback - this will be called when the response arrives
extern fn http::on_response(status, body, headers) {
if (status == 200) {
std::print(str::fmt("Success! Response: {}", body))
} else {
std::print(str::fmt("Error: HTTP {}", status))
}
}
// Prepare and send the request
client = http::client()
http::set_method(client, "GET")
http::set_header(client, "Accept", "application/json")
http::call(client, "http://192.168.1.100/api/status")
// For POST request with data
client2 = http::client()
http::set_method(client2, "POST")
http::set_header(client2, "Content-Type", "application/json")
http::set_body(client2, """{"command": "turn_on"}""")
http::call(client2, "http://192.168.1.100/api/device/relay1")
# TCP 操作
このセクションでは、生の TCP 通信を行う関数について説明します。HTTP が使えない PLC、メディア コントローラ、産業用ゲートウェイなど、TCP 上で独自のバイナリまたはテキスト プロトコルを話すデバイスやサービスと Volang スクリプトが通信できます。
2 つの利用モデルがあります。短いリクエスト/応答のやり取りには tcp::oneshot が 1 回の呼び出しで一連の処理を行います。接続を開いたまま複数メッセージをやり取るプロトコルには、tcp::open、tcp::send、tcp::receive、tcp::close を使います。
注意: Volang プログラムが同時に保持できる TCP 接続は 1 つだけ です。新しい接続を開く前に、
tcp::close()で現在の接続を閉じてください。
# tcp::oneshot
1 回の呼び出しで TCP 通信の一連の処理を行います。指定アドレスへ接続を開き、リクエスト バイトを送信し、応答を読み取ってから接続を閉じます。この関数は非同期で、通信を開始してすぐに戻ります。応答を受信したとき、期待バイト数に達したとき、または操作が失敗したときに、結果が on_result コールバックへ届きます。
接続ごとに 1 メッセージを送り 1 件の応答を期待する、短いリクエスト/応答プロトコル向けです。
パラメータ:
sa(string): リモート ホストのソケット アドレス。"host:port"形式 (例:"192.168.1.50:9100")。din: 送信するリクエスト データを保持するバイト配列 (array::newで作成)。各要素は0から255の範囲のバイト値。exrs(integer): 期待する応答サイズ (バイト)。通信を完了する前に、このバイト数まで読み取ります。on_result(string): 結果を受け取るextern fnコールバックの名前。関数は同じスクリプト内で定義する必要があります。
戻り値:
- なし。結果は
on_resultコールバック経由で非同期に届きます。
コールバック: on_result(result, dout)
on_result で指定したコールバックは、同じスクリプト内で extern fn 構文で宣言する必要があります:
extern fn on_result(result, dout) {
// Handle the response here
}
コールバック パラメータ:
result(integer): 通信が成功した場合は0、失敗した場合は-1(接続確立不可、タイムアウト、期待データ到着前の切断など)。dout: 応答バイトを含むバイト配列。失敗時は配列が空の場合があります。
例:
// Handle the response once the exchange completes
extern fn on_result(result, dout) {
if (result != 0) {
// Mark the device as unreachable
output::set("online", false)
return
}
// Read the first byte of the response and expose its state
if (array::len(dout) > 0) {
status = array::get_at(dout, 0)
output::set("online", true)
output::set("status", status)
}
}
// Build the request payload as a byte array
request = array::new(0x01, 0x03, 0x00, 0x00)
// Send 4 bytes and expect an 8-byte reply
tcp::oneshot("192.168.1.50:9100", request, 8, "on_result")
# tcp::open
指定ソケット アドレスへ TCP 接続を確立します。接続は tcp::close() で閉じるか、リモート側が切断するまで開いたままです。接続が開くと、tcp::send と tcp::receive で利用されます。
プログラムが保持できる TCP 接続は 1 つだけなので、すでに接続がある状態でこの関数を呼ぶとエラーになります。先に既存の接続を閉じてください。
パラメータ:
addr(string): リモート ホストのソケット アドレス。"host:port"形式 (例:"192.168.1.50:4998")。
戻り値:
- なし。
例:
// Connect to a device that speaks a persistent TCP protocol
tcp::open("192.168.1.50:4998")
// The connection is now available for tcp::send and tcp::receive
# tcp::close
現在開いている TCP 接続を閉じます。この呼び出し後、プログラムは接続を保持せず、同じアドレスでも別のアドレスでも tcp::open で新しい接続を確立できます。
パラメータ:
- なし。
戻り値:
- なし。
例:
// Finished talking to the device - release the connection
tcp::close()
// A new connection can now be opened
tcp::open("192.168.1.60:4998")
# tcp::send
現在開いている TCP 接続経由でデータを送信します。この関数は非同期で、送信データをキューに入れてすぐに戻ります。送信完了時または送信失敗時に、結果が on_sent コールバックへ届きます。
パラメータ:
data: 送信するデータを保持するバイト配列 (array::newで作成)。各要素は0から255の範囲のバイト値。on_sent(string): 結果を受け取るextern fnコールバックの名前。関数は同じスクリプト内で定義する必要があります。
戻り値:
- なし。結果は
on_sentコールバック経由で非同期に届きます。
コールバック: on_sent(result)
on_sent で指定したコールバックは、同じスクリプト内で extern fn 構文で宣言する必要があります:
extern fn on_sent(result) {
// Handle the send result here
}
コールバック パラメータ:
result(integer): データ送信が成功した場合は0、エラーが発生した場合は-1。
例:
extern fn on_sent(result) {
if (result == 0) {
std::print("Command sent")
} else {
// Sending failed - the connection is likely broken
output::set("online", false)
}
}
tcp::open("192.168.1.50:4998")
// Send a 3-byte command
command = array::new(0x02, 0x10, 0x03)
tcp::send(command, "on_sent")
# tcp::receive
現在開いている TCP 接続に 2 つのコールバックを登録します。1 つはデータ到着のたびに、もう 1 つは接続が閉じられたまたは失われたときに呼び出されます。この関数はすぐに戻り、接続上でイベントが起きるとシステムがコールバックを呼び出します。
パラメータ:
on_data(string): 接続がデータを受信したときに呼び出すextern fnコールバックの名前。関数は同じスクリプト内で定義する必要があります。on_closed(string): リモート側により接続が閉じられた、または切断されたときに呼び出すextern fnコールバックの名前。関数は同じスクリプト内で定義する必要があります。
戻り値:
- なし。受信データと接続切断は、コールバック経由で非同期に届きます。
コールバック: on_data(bytes)
extern fn on_data(bytes) {
// Process the received bytes here
}
コールバック パラメータ:
bytes: 受信データを含むバイト配列。
警告: The
bytesarray is only valid during the callback execution. After the callback returns, its contents are overwritten by the next incoming data. TCP is a stream protocol, so a single callback may deliver a partial message or several messages at once. Assembling complete messages is the script's responsibility: copy the bytes you still need into a state variable, typically an array state variable used as a receive buffer, since global variables are not accessible inside functions.
コールバック: on_closed()
extern fn on_closed() {
// React to the connection being closed or lost
}
コールバック パラメータ:
- なし。
例:
// The device sends 2-byte status frames: [frame type, value].
// A frame may arrive split across two callbacks, so incoming bytes
// are collected in the "rx_buffer" array state variable.
extern fn on_data(bytes) {
buf = state::get("rx_buffer")
// Append the new bytes to the buffered ones
i = 0
while (i < array::len(bytes)) {
array::append(buf, array::get_at(bytes, i))
i = i + 1
}
// Process every complete 2-byte frame
i = 0
while (i + 1 < array::len(buf)) {
frame_type = array::get_at(buf, i)
value = array::get_at(buf, i + 1)
if (frame_type == 0x01) {
output::set("status", value)
}
i = i + 2
}
// Keep the unconsumed byte (if any) for the next callback.
// "buf" is a shared handle to the state array, so no state::set
// is needed - these modifications update the state directly.
if (i < array::len(buf)) {
leftover = array::get_at(buf, i)
array::clear(buf)
array::append(buf, leftover)
} else {
array::clear(buf)
}
}
extern fn on_closed() {
// The device dropped the connection
output::set("online", false)
}
tcp::open("192.168.1.50:4998")
tcp::receive("on_data", "on_closed")
output::set("online", true)
# 時間操作
# time::now
現在のシステム時刻を Unix タイムスタンプとして取得します。値は 1970 年 1 月 1 日 00:00:00 UTC (Unix エポック) から経過した秒数を表します。
イベント発生時刻の記録、操作間の経過時間の計算、外部サーバーとの同期などに欠かせません。
パラメータ:
- なし。
戻り値:
- 現在の Unix タイムスタンプ (秒) を表す整数値。
例:
// Store the time when the motion was last detected
last_motion_time = time::now()
// ... later in the code ...
// Check if more than 60 seconds have passed since the last motion
if (time::now() > last_motion_time + 60) {
...
}
# time::uptime
モジュールの電源投入または最後の再起動から経過した秒数を返します。システムの健全性監視、想定外の再起動の検出、電源サイクル後にリセットすべき時間ベース ロジックの実装に便利です。
絶対タイムスタンプを提供する time::now() と異なり、time::uptime() はモジュール起動のたびに 0 から始まる相対的な計測値を提供します。
パラメータ:
- なし。
戻り値:
- モジュール起動からの秒数を表す整数値。
例:
// Log a warning if the module has been running for more than 24 hours
// (might indicate it hasn't been restarted for maintenance)
if (time::uptime() > 86400) {
std::print("Module running for over 24 hours")
}
// Delay initialization logic until the module has been stable for 10 seconds
if (time::uptime() > 10) {
// Safe to assume all sensors have initialized
...
}
// Detect if the module was recently restarted
if (time::uptime() < 60) {
std::print("Module just started, initializing...")
}
# 数学操作
# math::abs
数値の絶対値を計算します。入力が負なら正の同等値を返し、正ならそのまま返します。整数と float の両方に対応します。
どちらの値が大きいかを気にせず、2 つのセンサー読み取り値の差 (デルタ) を求めるのに特に便利です (たとえば、温度がどちら向きにも 1 度以上変化したかを確認する場合)。
パラメータ:
value: 処理対象の数値。
戻り値:
- 入力の非負値を表す数値。戻り値の型は入力型と一致します。
例:
target_temp = 21.0
current_temp = 19.5
// Calculate the difference ignoring direction
delta = math::abs(target_temp - current_temp)
// If the difference is significant (more than 0.5 degrees), take action
if (delta > 0.5) {
....
}
# math::round
指定した浮動小数点数を最も近い整数値に丸めます。ちょうど 0.5 になる中間値は、0 から離れる方向に丸められます。
パラメータ:
value: 丸める数値。
戻り値:
- 最も近い整数を表す整数値。
例:
// Example 1: Rounding sensor data for display
rawTemp = 21.7
displayTemp = math::round(rawTemp) // Returns 22
// Example 2: Halfway cases (rounding away from zero)
val1 = math::round(2.5) // Returns 3
val2 = math::round(-2.5) // Returns -3
// Setting a dimmer level (must be an integer 0-100)
calculatedLevel = 55.4
dimmerLevel = math::round(calculatedLevel) // Returns 55
# math::random
[0.0, 1.0) の範囲の疑似乱数 (浮動小数点数) を返します。呼び出すたびに異なる値が生成されます。結果をスケールし、math::round と組み合わせると、希望範囲内の乱数整数を作れます。
パラメータ:
なし。
戻り値:
0.0以上1.0未満の float 値。
例:
// Get a random value between 0.0 and 1.0
r = math::random()
// Generate a random integer between 1 and 100
n = math::round(math::random() * 100) + 1
// Random boolean decision (50/50)
if (math::random() < 0.5) {
output::set("led", true)
} else {
output::set("led", false)
}
# Base64 操作
このセクションでは、Base64 エンコード方式でデータを符号化する関数について説明します。
# base64::encode
標準アルファベット (RFC 4648 Table 1) を使って文字列を Base64 表現にエンコードします。出力は A-Z、a-z、0-9、+、/ を使い、出力長が 4 の倍数になるよう = でパディングします。
パラメータ:
data(string): エンコード対象の入力文字列。
戻り値:
- 入力の Base64 エンコード表現を含む文字列。
例:
// Encode a simple string
encoded = base64::encode("Hello, World!") // Returns "SGVsbG8sIFdvcmxkIQ=="
// Encode credentials for HTTP Basic Auth
credentials = str::concat("user", ":", "password")
auth = str::concat("Basic ", base64::encode(credentials))
http::set_header(client, "Authorization", auth)
// Empty string encodes to empty string
encoded = base64::encode("") // Returns ""
# base64::url_encode
URL セーフ アルファベット (RFC 4648 Table 2) を使って文字列を Base64url 表現にエンコードします。出力は A-Z、a-z、0-9、-、_ を使い、パディング文字は 含みません。URL、クエリ パラメータ、JWT セグメントでの利用に安全です。
パラメータ:
data(string): エンコード対象の入力文字列。
戻り値:
- パディングなしの Base64url エンコード表現を含む文字列。
例:
// Encode for URL-safe usage
encoded = base64::url_encode("Hello, World!") // Returns "SGVsbG8sIFdvcmxkIQ"
// Build a JWT header and payload
header = base64::url_encode("""{"alg":"RS256","typ":"JWT"}""")
payload = base64::url_encode("""{"sub":"1234567890","name":"John"}""")
signing_input = str::concat(header, ".", payload)
// Note the difference from standard base64:
// base64::encode("subjects?_d") returns "c3ViamVjdHM/X2Q="
// base64::url_encode("subjects?_d") returns "c3ViamVjdHM_X2Q"
# 暗号操作
このセクションでは、暗号処理を行う関数について説明します。
# crypto::rs256_sign
RS256 アルゴリズム (SHA-256 を使う RSASSA-PKCS1-v1_5) で RSA 秘密鍵を使い、データに署名します。JWT 署名やその他の認証付きメッセージの作成に通常使われます。
パラメータ:
data(string): 署名対象のデータ。private_key_pem(string): PEM 形式の RSA 秘密鍵。
戻り値:
- Base64url エンコードされた署名を含む文字列。
例:
// Create a JWT signature
header = base64::url_encode("""{"alg":"RS256","typ":"JWT"}""")
payload = base64::url_encode("""{"sub":"device-001","iat":1700000000}""")
signing_input = str::concat(header, ".", payload)
// Sign with the private key
signature = crypto::rs256_sign(signing_input, private_key)
// Assemble the complete JWT
jwt = str::concat(signing_input, ".", signature)
