String Length — Control Systems/Strings
Control_Systems/Strings/String_Length · 1 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
String Length
Control Systems / Strings
Reports how long the incoming text is, as a number you can compare, plot or feed to anything else: y = the length of u in bytes.
Ports
- Input – the text u (
str,ICoreString). Only text: this block has nothing to say about a number. - Output – the length y (
u32,ICoreUInt32), one value. A length is never negative, so it is an unsigned integer, and it can never exceed 256.
Parameters
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Bytes, not characters
The length is counted in bytes of UTF-8. For ordinary English text those are the same number. They stop being the same the moment the text contains an accented letter, a non-Latin script or an emoji: "café" is four characters and five bytes.
Bytes is the answer that matches everything else about a text signal here: the 256-byte limit a text signal is cut at is a limit in bytes, and the buffer exported C stores it in is 256 bytes. A length in characters could come back larger than the buffer that held the text.
Code export
C, C++, Python, MATLAB, Java and Rust all report the same byte count. Each of those languages has its own built-in idea of "length" – some count characters, some count 16-bit units – so the generated code spells out the byte count rather than using the built-in, and every target answers the same number as the simulation for every input.
VHDL, Verilog and SystemVerilog do not carry text, and PLC Structured Text is not supported either: the language has a string type, but the check that runs an exported core cannot read one back. Since this block's input is always text, an export to any of these four stops and names this block and the reason.
Simulink bridge
Import and export, mapped to simulink/String/String Length, whose
output is set to uint32 to match. The Simulink block has no
sampling-time setting of its own, so a positive Sampling Time (s) stays
on this side and is reported rather than written.
Simulink counts characters where this block counts bytes: given "café" it answers 4, where this block answers 5. The two agree for any text that is plain ASCII, which is what the parity benches use; they disagree by design on text that is not, and that difference is here rather than hidden.
Notes
- Algebraic, with no state: the output depends only on the current input.
- An unconnected input is empty text, so the length is 0.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Strings/String_Length |
| family | Control_Systems/Strings |
| solver environment class | ICoreBlock_0_Control_Systems_1_Strings_2_String_Length |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Strings/String_Length/ICoreBlock_0_Control_Systems_1_Strings_2_String_Length.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Strings/String_Length/ICoreBlock_0_Control_Systems_1_Strings_2_String_Length.h |
| default size on canvas | 90 × 60 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++ |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreString | — |
| 2 | out | ICoreUInt32 | — |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
No config variable beyond the Sampling Time (s) every block carries.
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::Both |
| Simulink path | simulink/String/String Length |
| port-count rule | PortsParam:: |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
Caveat (shown to the user): "Simulink counts CHARACTERS and this block counts BYTES of UTF-8
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
String Length -- the crossing from a text signal back to a number y = the number of BYTES of UTF-8 in u. One input carrying text, one output carrying an unsigned 32-bit integer, and the interesting part is entirely in the word "bytes": see the header for why every generator below spells the byte count out rather than calling its language's own length function.
This is also the block that proves a String signal can be CONSUMED. String Constant proves one can be produced; a diagram of the two, with the length reaching a Display, is the smallest end-to-end typed String path there is.
Sample results#
This block carries a ICoreString signal, whose value is text rather than a number and is not something a plot has an axis for. The samples are in the table below, exactly as the run recorded them.
| t | in ICoreString-Out-0 | out ICoreUInt32-Out-0 |
|---|---|---|
| 0 | u0 | 2 |
| 0.4 | u0 | 2 |
| 0.8 | u0 | 2 |
| 1.2 | u0 | 2 |
| 1.6 | u0 | 2 |
| 2 | u0 | 2 |
| 2.4 | u0 | 2 |
| 2.8 | u0 | 2 |
| 3.2 | u0 | 2 |
| 3.6 | u0 | 2 |
| 4 | u0 | 2 |
| 4.4 | u0 | 2 |
| 4.8 | u0 | 2 |
| 5.2 | u0 | 2 |
Every 4th of 60 samples, from the table stimulus.
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 2 … 2 |
ramp | Ramp: slope 1 from t = 0 | 2 … 2 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 2 … 2 |
step | Step: 0 -> 1 at t = 1 s | 2 … 2 |
Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample
Category static · sample time 0.1 · 60 steps · commit 6280f52f3 · produced by docsSample --out <folder> --blocks Rational_Resample,Three_Axis_Accelerometer,Three_Axis_Gyroscope,Three_Axis_Inertial_Measurement_Unit,Eclipse_Shadow_Model,To_String,String_To_ASCII,ASCII_To_String,Substring,String_Constant,String_Concatenate,String_Compare,String_Length --steps 60 · data docs/generated/samples/Control_Systems__Strings__String_Length.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).