unsigned short may or may not be 2 bytes. Let's look at the memory for your example.
+---+---+---+ +---+---+---+
| | | | ... | | | |
+---+---+---+ +---+---+---+
|<-------- len bytes -------->|
If unsigned short is 2 bytes long, you have space worth of len/2 unsigned short values. Or, more generally, you have space for len/n unsigned short values, where n is equal to sizeof(unsigned short).
You can't cast an unsigned char * to unsigned char * and expect things to work portably. Now, to calculate peak, it depends upon what you are trying to do. If you want to find the maximum of len unsigned char values, and save that into peak, looping over the values will work:
size_t i;
unsigned short peak = 0;
for (i=0; i < len; ++i) {
if (buffer[i] > peak) {
peak = buffer[i];
}
}
If, however, you want to "combine" sizeof(unsigned short) values into one unsigned short value, then your best bet would be to calculate the numbers by hand.
Assuming that len is divisible by n, and big-endian storage, you can do something like this (untested):
#include <stdio.h>
#include <limits.h>
size_t factor = sizeof(unsigned short);
size_t n = len / factor;
size_t i;
unsigned short peak = 0;
if (len % factor != 0) {
fprintf(stderr, "Extra data at the end\n");
}
for (i=0; i < n; ++i) {
size_t j;
unsigned short test = 0;
for (j=0; j < factor; ++j) {
test = (test << CHAR_BIT) + buffer[i*factor+j];
}
if (test > peak) {
peak = test;
}
}