Anytime Help Center

Calculating big file checksums and the 16000 byte string expression limit

Rating

Occasionally a NetLinx Programmer may have to work with a CHAR array of 16000 bytes or longer. Most commonly this is the result of a FILE_READ(), or maybe from a CREATE_BUFFER via web scraper or virtual device code.

If the NetLinx Programmer puts double-quotes "" around the array, he will find the array has been truncated to 15999 bytes, and in certain cases it can be truncated to as little as 2048 bytes.

The NetLinx interpreter allocates a fixed buffer size to deal with string expressions.

The maximum length of a string expression NetLinx is 15999 bytes. Put any CHAR array in double-quotes, it can never be longer than this.

The default length of a string expression passed into a subroutine is 2048 bytes.

If you're using unbounded CHAR arrays for subroutine parameters, string expressions will be truncated to 2048 bytes.

For example:

DEFINE_FUNCTION processBigString(CHAR str[])

{

  STACK_VAR LONG Length

  // if str[] is fed by a string expression, Length will never be greater than 2048

  Length = LENGTH_ARRAY(str)

}

You may realize from all this that string concatenation of the form newStr = "str1,'some text','etc',str2" won't work to create a string longer than 15999 bytes.

The right side of that statement is a string expression, so it will be truncated.

Resolution

As long as you don't put it in double-quotes, a CHAR array is only limited by its maximum size and available memory.

What is interesting is what the limit does not affect:

  • The size of a CHAR array fed by CREATE_BUFFER
  • The size of a CHAR array fed by FILE_READ()
  • The CHAR array returned by GET_BUFFER_STRING()
  • Etc…

There are a number of ways to work around the concatenation problem:

Workaround 1:

Create a buffer on a virtual device, and then send strings to the virtual.

If you are doing a FILE_READ() to buffer the data from a file, the best size for max-bytes-to-read is 2008.

If you try to read more data, the SEND_STRING to the virtual will be split into multiple packets – some 2008 bytes, some 4 bytes, some may be other sizes. Also, the maximum size of a FILE_READ() appears to 31212 bytes when the file buffer is immediately sent to a virtual.

Stick to 2008 byte reads and all the packets will be 2008 bytes.

Possible problem: the interpreter may pend when sending large amounts of data to the virtual device.

If you have to copy a large amount of data, use Workaround 3.

Workaround 2:

Write/append the strings to a file on the master. You can then reopen the file and read it into a buffer. Possible problem: the interpreter may pend when writing large amounts of data to a file.

If you have to copy a large amount of data, use Workaround 3.

Workaround 3:

Do a FOR loop byte-by-byte copy of the new data to a buffer, then set the length of the buffer to the desired size with SET_LENGTH_ARRAY() or SET_LENGTH_STRING(). If you have to copy a large amount of data, this is probably the best option as the events or file writes of the other two methods will have priority over the interpreter and may cause the copy to fail. In real world use, you may only need to shift data in your buffer using MID_STRING() or RIGHT_STRING(), then copy in the new data byte-by-byte. The size of the buffer in any case is limited by available memory on the NetLinx master.

Be sure you define the buffer as VOLATILE, NetLinx masters only have 1M or less of non-volatile memory.

The crc32 Example

The attached code block is an example of working with large arrays. It can open a file on the master, and calculate a crc32 on the file.

If the file is passed into the processing subroutines with quotes, it is truncated to 2048 bytes if passed in via an unbounded CHAR array, and 15999 if passed in via a CHAR array of 15999 bytes or greater.

If the file buffer is passed into the processing subroutines without quotes, the crc32 is calculated correctly.

To run the example:

  1. Compile and load the code into a NetLinx master.
  2. FTP the provided jaws.bin file to the root directory of the master. This 96848 byte file has a crc32 of 0x93c24b86. Or optionally, FTP another file you would like to test.
  3. Open a telnet or terminal session, type: msg on<enter>
  4. To list the files in the masters user directory, type: send c 33000,'ls'<enter>
  5. To open jaws.bin for crc32 calculation, type: send c 33000,'open-jaws.bin'
  6. Enjoy the results.

Note: Example workspace, code, and jaws.bin are in the attached AXW.

The attached code example uses the TN461 debug.axi, checksum.axi, and file.axi.


Last modified at 7/27/2023 9:56 AM by PRO Knowledge Base
Top