private static String readUTF(byte[] buffer, int offset, int len) throws UTFDataFormatException
        {
            char[] charArray = new char[len];

            int i = 0;
            int c = 0;

            // Optimizaiton: Assume that the characters are all 7-bits encodable
            // (which is most likely the standard case).
            // If they're not, break out and take the 'slow' path.
            for (; i < len; i++)
            {
                int ch = (int) buffer[offset + i] & 0xff;

                // If it's not 7-bit character, break out
                if (ch > 127)
                    break;

                charArray[c++] = (char) ch;
            }

            // 'Slow' path
            while (i < len)
            {
                int ch = (int) buffer[offset + i] & 0xff;

                // Determine how to decode based on 'bits of code point'
                // See: http://en.wikipedia.org/wiki/UTF-8#Description
                int upperBits = ch >> 4;

                if (upperBits <= 7)
                {
                    // 1-byte: 0xxxxxxx
                    charArray[c++] = (char) ch;
                    i++;
                }
                else if (upperBits == 0x0C || upperBits == 0x0D)
                {
                    // 2-byte: 110xxxxx 10xxxxxx
                    i += 2;

                    if (i > len)
                        throw new UTFDataFormatException("Malformed input: Partial character at end");

                    int ch2 = (int) buffer[offset + i - 1];

                    // Make sure the second byte has the form 10xxxxxx
                    if ((ch2 & 0xC0) != 0x80)
                        throw new UTFDataFormatException("Malformed input around byte " + i);

                    charArray[c++] = (char) (((ch & 0x1F) << 6) | (ch2 & 0x3F));
                }
                else if (upperBits == 0xE)
                {
                    // 3-byte: 1110xxxx 10xxxxxx 10xxxxxx
                    i += 3;

                    if (i > len)
                        throw new UTFDataFormatException("Malformed input: Partial character at end");

                    int ch2 = (int) buffer[offset + i - 2];
                    int ch3 = (int) buffer[offset + i - 1];

                    // Check the 10xxxxxx 10xxxxxx of second two bytes
                    if (((ch2 & 0xC0) != 0x80) || ((ch3 & 0xC0) != 0x80))
                        throw new UTFDataFormatException("Malformed input around byte " + (i - 1));

                    charArray[c++] = (char) (((ch & 0x0F) << 12) | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F));
                }
                else
                {
                    // 4-byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
                    upperBits = ch >> 3;
                    if (upperBits == 0x1E)
                    {
                        // Because we're now in the UTF-32 bit range, we must
                        // break it down into the UTF-16 surrogate pairs for
                        // Java's String class (which is UTF-16).

                        i += 4;
                        if (i > len)
                            throw new UTFDataFormatException("Malformed input: Partial character at end");

                        int ch2 = (int) buffer[offset + i - 3];
                        int ch3 = (int) buffer[offset + i - 2];
                        int ch4 = (int) buffer[offset + i - 1];

                        int value =
                                ((ch & 0x07) << 18) |
                                        ((ch2 & 0x3F) << 12) |
                                        ((ch3 & 0x3F) << 6) |
                                        ((ch4 & 0x3F));

                        charArray[c++] = highSurrogate(value);
                        charArray[c++] = lowSurrogate(value);
                    }
                    else
                    {
                        // Anything above
                        throw new UTFDataFormatException("Malformed input at byte " + i);
                    }
                }
            }

            return new String(charArray, 0, c);
        }
Reads the string from a byte[] using that was encoded a using Modified UTF-8 format. Additionally supports
4-byte surrogates, de-serializing them as surrogate pairs.

See: http://en.wikipedia.org/wiki/UTF-8#Description for encoding details.
protostuff-api/src/main/java/io/protostuff/StringSerializer.java