9. nString

NodeWire uses a lot of strings for its logic. In order to help handle the string manipulation easily in a memory safe way, we created the nString class. nString is a class that points to a normal c string (pointer to chars) and then provide high level functions for appending, copying, and comparison operations. It can also convert between string and other types such as int and float.

nString can also be used to store and manipulate arrays and dictionaries and can be used to encode and decode JSON objects.

nString requires a string buffer (char*). And this can be created externally, in which case managing the buffer is the responsibility of the programmer. Or it can be created internally by nString, in which case the string is managed by the class. A managed string can automatically expand to accommodate longer strings during assignment, concatenation and other operations.

9.1. Creating nString

char buffer[100];
nString greeting(buffer, 100);

or

char buffer[100];
nString greeting;
greeting.setBuffer(buffer, 100);

This creates a user managed string.

avoid this:

nString greeting(new char[100], 100);

or this:

nString greeting(new char[100]);

But you can do this:

nString greeting("hello world");

and this

nString greeting = "hello world";

9.2. Copying

You can copy into a string by using the assignment operation. No new memory is allocated in this process unless if the nString has not previously been assigned a buffer.

#include <nstring2.h>
void setup()
{
  Serial.begin(38400);
  char buffer[100];
  nString greeting(buffer, sizeof(buffer));

  greeting = "hello world";
  greeting.println(&Serial);
}
void loop()
{
}

this copies the characters “hello world” to the buffer associated with the nString.

9.3. Appending

To append a string to an existing string, use the + operator:

char buffer[100];
nString greeting(buffer, sizeof(buffer));

greeting = "hello ";
greeting = greeting + "world";

or

char buffer[100];
nString greeting(buffer, sizeof(buffer));

greeting = "hello ";
greeting += "world";

it is also possible to append to an nString without first associating it with a buffer.

nString greeting;

greeting = "hello ";
greeting += "world";

But in this case, nString will dynamically allocate memory and reallocate as needed tp accommodate the characters. The buffer is managed by nString and it will be deleted by nString’s destructor.

9.4. Comparison

You can make string comparisons:

if(greeting == "hello") Serial.println("correct");

Note that the nString will truncate the result if the buffer is user allocated otherwise the buffer will grow to accommodate the result..

When appending, (+) operator, always make sure that the leftmost variable on the right hand side of the equation has enough space in its buffer to hold the result.

9.5. Accessing the buffer

You can access the buffer by making reference to the original c string (char pointer) or by using the nString’s internal reference:

char buffer[100];
nString greeting(buffer, sizeof(buffer));

greeting = "hello ";
greeting += "world";

Serial.println(buffer);
Serial.println(greeting.theBuf);
Serial.println((char*)greeting);

The last 3 lines are all equivalent

9.6. Using nString as an Array

You can convert an nString to an array either to splitting the string in its buffer or by explicitly calling the create_array member function.

char buffer[100];
nString greeting(buffer, sizeof(buffer));

greeting = "these will be the elements";
greeting.split(' ');

greeting[1] = "wont"; // change item 1

for(int i=0; i<greeting.len; i++)
{
  Serial.println(greeting[i].theBuf);
}

greeting.join(' '); // convert back to string
Serial.println(greeting.theBuf);

The split function does not create any new buffer. It splits the buffer of the parent nString among the elements, each according to its size. The last element will take whatever is left. Note that while you can modify the elements of the array, the size of the elements are limited to their initial sizes and assigning any string longer than that will result in truncation.

The join function converts an array back to string using the character specified to join them.

The second method for creating an Array is by calling the create_array member function and passing the number of elements as a parameter. This requires that the nString already has a buffer. The buffer is split equally into the elements of the array created.

char buffer[100];
nString greeting(buffer, sizeof(buffer));
greeting.create_array(10);
greeting.append("one");
greeting.append("two");
greeting.append("three");
greeting.append("four");

greeting.pop();

for(int i=0; i<greeting.len; i++)
{
  Serial.println(greeting[i].theBuf);
}

greeting[1]  = "twenty";
greeting.append("five");

int third = greeting.find("three");
if(third!=-1)
  greeting[third] = "Thirty";

greeting.join(' ');
Serial.println(greeting.theBuf);

9.7. Using nString as Object

There are two ways to create an nString object:

  1. First create an Array. Then call the convert_object member function to convert it to an object
  2. Call the create_object member function.

Both functions text a string which lists the fields of the new object, separated by space.

Example:

char buffer[100];
nString obj(buffer, sizeof(buffer));
obj.create_object("name age department");
obj["name"] = "Ahmad";
obj["age"] = 35;
obj["department"] = "software";

obj.println(&Serial);

This can also be achieved by starting with an array:

char buffer[100];
nString obj(buffer, sizeof(buffer));
obj = "Ahmad 35 software";
obj.split(' ');
obj.convert_object("name age department");

obj.println(&Serial);

9.8. Decoding and Encoding Json

nString can be used to decode (parse) and encode (dump) json objects.

Decoding

To create an nString object from a json string,

nString obj = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
obj.parse_as_json();
Serial.println((char*)obj["sensor"]);
Serial.println((long)obj["time"]);
Serial.println((char*)obj["data"][0]);
Serial.println((char*)obj["data"][1]);

Encoding

To convert an nString Object to a JSON string:

char buff[50];//where we will store the json string
nString list = "one two three four";
list.split(' '); //create array
list.dump_json(buff);//convert to json
Serial.println(buff);

9.9. Parsing PlainTalk

#include <nstring2.h>

void setup() {
  Serial.begin(38400);
  nString dval = "node01 set person {\"name\": \"ahmad\", \"score\": 80} lrsnr49yxurz:re";
  dval.splitPT(' ');
  dval.convert_object("address command port value sender");
  dval["value"].parse_as_json();

  Serial.println((char*)dval["value"]["name"]);
  Serial.println((char*)dval["value"]["score"]);

  dval["value"].println(&Serial);
}

void loop()
{

}