2
\$\begingroup\$

This is a component for a lexer which operates on a byte input stream that handles reading and decoding the contents of a string contained within double-quotes. The validity of the encoding is handled by CharsetDecoder#decode() which will throw an exception on an invalid buffer.

The charset argument defines the encoding of the string contents not the encoding of the quotation marks themselves (which is defined by the lexer). This allows the contents of the string to be defined as a character set other than the parent document. However, it must be a valid subset of Unicode such that its contents do not erroneously contain a byte value to match code point 34. Some form of readHeredoc() could provide an alternative for this specific use case.

String readString(
   Reader r,
   Charset charset)
   throws IOException
{
   ByteArrayOutputStream ostream = new ByteArrayOutputStream();

   int cp;

   while ((cp = r.read()) > 0) {
      if (cp == '"')
         break;

      ostream.write(cp);
   }

   return charset.newDecoder().decode(ByteBuffer.wrap(ostream.toByteArray()))
      .toString();
}

Reaching the end the buffer before a matching quotation is not handled; I haven't decided on the defined behavior for this and its absence is known.

\$\endgroup\$
  • 1
    \$\begingroup\$ Reaching the end the buffer before a matching quotation is not handled but will likely end up throwing an exception - and that's desired? If so, feel free to edit to clarify; note that asking for help fixing code that doesn't work as intended is out-of-scope on this site. \$\endgroup\$ – Mathieu Guindon Mar 18 at 2:14
  • 2
    \$\begingroup\$ It's not handled, as in I haven't decided on the defined behavior and its absence is known. I made note of it as it would otherwise be something to point out in a code review. \$\endgroup\$ – Zhro Mar 18 at 2:39
  • 3
    \$\begingroup\$ Fair enough, and that is correct - just pointing out, since we require that the code you put up for review works as intended to the best of your knowledge, that some readers might mistake the statement for a request to help with debugging it, which would be off-topic here. Hence, and since one person already put in what appears to be an erroneous vote to close, my suggestion to edit to clarify. Feel free to ignore, as far as I can tell there's nothing wrong with your post, although more context wouldn't hurt (it never does). \$\endgroup\$ – Mathieu Guindon Mar 18 at 2:43
  • 2
    \$\begingroup\$ This question seems to lack context of the whole class, it would be better if we could see the code that calls it as well. \$\endgroup\$ – pacmaninbw Mar 19 at 17:36
0
\$\begingroup\$

the only advice, that I can give you, is to separate the logic in multiple methods. This will make your method shorter and allow the code to be reused.

Personally, I see two other methods.

    String readString(Reader r, Charset charset) throws IOException {
        ByteArrayOutputStream ostream = copyInputToStream(r);

        final ByteBuffer byteBuffer = ByteBuffer.wrap(ostream.toByteArray());

        return decodeBufferAsString(charset, byteBuffer);
    }

    private String decodeBufferAsString(Charset charset, ByteBuffer byteBuffer) throws CharacterCodingException {
        return charset.newDecoder().decode(byteBuffer).toString();
    }

    private ByteArrayOutputStream copyInputToStream(Reader reader) throws IOException {
        ByteArrayOutputStream ostream = new ByteArrayOutputStream();

        int cp;

        while ((cp = reader.read()) > 0) {

            if (cp == '"') {
                break;
            }

            ostream.write(cp);
        }

        return ostream;
    }
| improve this answer | |
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.