/** * Serializes the {@code messages} into the stream using the given schema with the supplied * buffer. */ public static <T> void writeListTo( OutputStream out, List<T> messages, Schema<T> schema, boolean numeric, LinkedBuffer buffer) throws IOException { if (buffer.start != buffer.offset) throw new IllegalArgumentException("Buffer previously used and had not been reset."); if (messages.isEmpty()) { System.arraycopy(EMPTY_ARRAY, 0, buffer.buffer, buffer.offset, EMPTY_ARRAY.length); buffer.offset += EMPTY_ARRAY.length; return; } final JsonXOutput output = new JsonXOutput(buffer, out, numeric, schema); output.writeStartArray(); boolean first = true; for (T m : messages) { if (first) { first = false; output.writeStartObject(); } else output.writeCommaAndStartObject(); schema.writeTo(output, m); if (output.isLastRepeated()) output.writeEndArray(); output.writeEndObject().clear(false); } output.writeEndArray(); LinkedBuffer.writeTo(out, buffer); }
private static LinkedBuffer writeUTF8Escaped( final String str, final WriteSink sink, final WriteSession session, LinkedBuffer lb) throws IOException { final int len = str.length(); if (len == 0) return lb; byte[] buffer = lb.buffer; int limit = buffer.length, offset = lb.offset, size = len; for (int i = 0; i < len; i++) { final char c = str.charAt(i); if (c < 0x0080) { final int escape = sOutputEscapes[c]; // System.out.print(c + "|" + escape + " "); if (escape == 0) { // nothing to escape if (offset == limit) { lb.offset = offset; lb = sink.drain(session, lb); offset = lb.offset; buffer = lb.buffer; limit = buffer.length; } // ascii buffer[offset++] = (byte) c; } else if (escape < 0) { // hex escape if (offset + 6 > limit) { lb.offset = offset; lb = sink.drain(session, lb); offset = lb.offset; buffer = lb.buffer; limit = buffer.length; } final int value = -(escape + 1); buffer[offset++] = (byte) '\\'; buffer[offset++] = (byte) 'u'; buffer[offset++] = (byte) '0'; buffer[offset++] = (byte) '0'; buffer[offset++] = HEX_BYTES[value >> 4]; buffer[offset++] = HEX_BYTES[value & 0x0F]; size += 5; } else { if (offset + 2 > limit) { lb.offset = offset; lb = sink.drain(session, lb); offset = lb.offset; buffer = lb.buffer; limit = buffer.length; } buffer[offset++] = (byte) '\\'; buffer[offset++] = (byte) escape; size++; } } else if (c < 0x0800) { if (offset + 2 > limit) { lb.offset = offset; lb = sink.drain(session, lb); offset = lb.offset; buffer = lb.buffer; limit = buffer.length; } buffer[offset++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); buffer[offset++] = (byte) (0x80 | ((c >> 0) & 0x3F)); size++; } else { if (offset + 3 > limit) { lb.offset = offset; lb = sink.drain(session, lb); offset = lb.offset; buffer = lb.buffer; limit = buffer.length; } buffer[offset++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); buffer[offset++] = (byte) (0x80 | ((c >> 6) & 0x3F)); buffer[offset++] = (byte) (0x80 | ((c >> 0) & 0x3F)); size += 2; } } session.size += size; lb.offset = offset; return lb; }