Skip to content

vladtepesch/ArduinoMicroStringTemplateEngine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ArduinoMicroStringTemplateEngine

Micro String Template Engine for Arduino.
A very simplistic string template engine that helps preventing the usage of string function to reduce heap fragmentation.

Purpose/The problem to solve

This "library" (actual it is a single cpp and header file) is supposed to clean string output code in Arduino environment.

While it seems to be easy to construct complex output string like Serial.println("hello "+myString+". It is a nice day"); this pattern has a number of hidden implications:

  • additional string objects are created in this steps
    • each of them uses dynamic memory
    • lot of different size memory allocations fragement the heap
    • more details take a reading here: majen1
  • strings created this way use doubled space
    • one instance in flash
    • one instance is copied to memory during startup

There are some ways how to circumvent this. Using as few operators as possible will prevent string object construction:

Serial.print("hello ");
Serial.print(myString);
Serial.println(". It is a nice day");

For larger texts this drastically reduces your program readability and makes it difficult to copy-past text/code from other places.

Solution

The idea by that this little helper tries to solve this, is by providing an easy way to provide a template string with some placeholders that are replaced by values from a provided array.

The "%0" to "%9" are the placeholder for the runtime supplied values. If the character after the '%' sign is no decimal digit or another '%' then just a single '%' is printed.

Example

Instead of creating a String with concatination (or '+') that results in many temporary objects write a template string and use this class:

    String name ("Dave");
    String game ("TicTacToe");
    
    ////// instead of 
    String a = "Hello, " + name + ".\n"
               "I want to play a game. "
               "Would you like to play \"" + game + "\" with me?" ;
    Serial.print(a);
   
    ////// use that
    //  array with template values:
    const char* values[] = {name->c_str(), game->c_str()};
    
    // (1) output to serial - template parameter is C string literal from RAM (initially copied from flash on startup)
    TemplatePrinter::printTo(Serial, "Hello, %0. I want to play a game. Would you like to play \"%1\" with me?", values);
    ////// or
    // (2) output to serial - template parameter is inline C string literal from FLASH (without being duplicated to RAM)
    TemplatePrinter::printTo(Serial, F("Hello, %0. I want to play a game. Would you like to play \"%1\" with me?"), values);
    // (3) output to serial - same as above but uses a pointer to a FLASH string literal
    static const char PROGMEM s_greeting[] = R"(Hello, %0. I want to play a game. Would you like to play "%1" with me?)";
    TemplatePrinter::printTo(Serial, FPSTR(s_greeting), values);

The above second method also makes it more easy to put whole strings into flash (see 3rd variant);

While in this little example it would be as easy to simply use Serial.printf(FPSTR(s_greeting), name.c_str()); (after replacing %0 by %s) this would be very cumbersome if the template is quite long and contains the same variables mutliple times.
However: there is a gcc-printf-extension that allows specifying the number of argument to place in (format string %2$s: use the second additional parsed argumend as string) but this extension is not supported everywhere.
On Arduino ESP8266 Core it seems not to work with the Print::printf functions

Limitations

  • currently only char* values are supported by the API
  • currently only tested on Arduino ESP8266 Core (but at least compiles for AVR)

About

Micro String Template Engine for Arduino

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages