comparison src/main/java/org/monetdb/jdbc/MonetConnection.java @ 616:65641a7cea31

Implement line ending conversion for downloads MonetConnection.Download#getStream returns an InputStream which converts line endings when in text mode. The default line ending is the platform line ending but that can be changed. Setting it to \n can be a useful optimization if you don't need the \r's anyway.
author Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com>
date Wed, 19 Jan 2022 14:58:01 +0100 (2022-01-19)
parents 9397c0b487f8
children 15eb17b911a5
comparison
equal deleted inserted replaced
615:34a15cd8cfc2 616:65641a7cea31
3223 return handleUpload(parts[2], true, offset); 3223 return handleUpload(parts[2], true, offset);
3224 } 3224 }
3225 } else if (transferCommand.startsWith("rb ")) { 3225 } else if (transferCommand.startsWith("rb ")) {
3226 return handleUpload(transferCommand.substring(3), false, 0); 3226 return handleUpload(transferCommand.substring(3), false, 0);
3227 } else if (transferCommand.startsWith("w ")) { 3227 } else if (transferCommand.startsWith("w ")) {
3228 return handleDownload(transferCommand.substring(2)); 3228 return handleDownload(transferCommand.substring(2), true);
3229 } else if (transferCommand.startsWith("wb ")) {
3230 return handleDownload(transferCommand.substring(2), false);
3229 } 3231 }
3230 return "JDBC does not support this file transfer yet: " + transferCommand; 3232 return "JDBC does not support this file transfer yet: " + transferCommand;
3231 } 3233 }
3232 3234
3233 private String handleUpload(final String path, final boolean textMode, final long offset) throws IOException { 3235 private String handleUpload(final String path, final boolean textMode, final long offset) throws IOException {
3248 server.setInsertFakePrompts(wasFaking); 3250 server.setInsertFakePrompts(wasFaking);
3249 } 3251 }
3250 return handle.getError(); 3252 return handle.getError();
3251 } 3253 }
3252 3254
3253 private String handleDownload(final String path) throws IOException { 3255 private String handleDownload(final String path, boolean textMode) throws IOException {
3254 if (downloadHandler == null) { 3256 if (downloadHandler == null) {
3255 return "No file download handler has been registered with the JDBC driver"; 3257 return "No file download handler has been registered with the JDBC driver";
3256 } 3258 }
3257 3259
3258 final Download handle = new Download(server); 3260 final Download handle = new Download(server, textMode);
3259 try { 3261 try {
3260 downloadHandler.handleDownload(handle, path, true); 3262 downloadHandler.handleDownload(handle, path, true);
3261 if (!handle.hasBeenUsed()) { 3263 if (!handle.hasBeenUsed()) {
3262 handle.sendError("Call to " + downloadHandler.getClass().getSimpleName() + ".handleDownload sent neither data nor error"); 3264 handle.sendError("Call to " + downloadHandler.getClass().getSimpleName() + ".handleDownload sent neither data nor error");
3263 } 3265 }
3465 /** 3467 /**
3466 * Handle passed to {@link DownloadHandler} to allow communication with the server 3468 * Handle passed to {@link DownloadHandler} to allow communication with the server
3467 */ 3469 */
3468 public static class Download { 3470 public static class Download {
3469 private final MapiSocket server; 3471 private final MapiSocket server;
3472 private boolean prependCr;
3470 private MapiSocket.DownloadStream stream = null; 3473 private MapiSocket.DownloadStream stream = null;
3471 private String error = null; 3474 private String error = null;
3472 3475
3473 Download(MapiSocket server) { 3476 Download(MapiSocket server, boolean textMode) {
3474 this.server = server; 3477 this.server = server;
3478 prependCr = false;
3479 if (textMode) {
3480 setLineSeparator(System.lineSeparator());
3481 }
3475 } 3482 }
3476 3483
3477 /** 3484 /**
3478 * Send an error message to the server 3485 * Send an error message to the server
3479 * 3486 *
3495 } 3502 }
3496 3503
3497 /** 3504 /**
3498 * Get an {@link InputStream} to read data from. 3505 * Get an {@link InputStream} to read data from.
3499 * 3506 *
3500 * Textual data is UTF-8 encoded. 3507 * Textual data is UTF-8 encoded. If the download is in text mode, line endings
3508 * are converted according to {@link java.lang.System#lineSeparator()}.
3509 * This can be overridden with {@link Download#setLineSeparator(String)}.
3501 */ 3510 */
3502 public InputStream getStream() throws IOException { 3511 public InputStream getStream() throws IOException {
3503 if (error != null) { 3512 if (error != null) {
3504 throw new IOException("cannot receive data after error has been sent"); 3513 throw new IOException("cannot receive data after error has been sent");
3505 } 3514 }
3506 if (stream == null) { 3515 if (stream == null) {
3507 stream = server.downloadStream(); 3516 stream = server.downloadStream(prependCr);
3508 server.getOutputStream().flush(); 3517 server.getOutputStream().flush();
3509 } 3518 }
3510 return stream; 3519 return stream;
3511 } 3520 }
3512 3521
3564 stream.close(); 3573 stream.close();
3565 stream = null; 3574 stream = null;
3566 } catch (IOException e) { 3575 } catch (IOException e) {
3567 /* ignore close error */ 3576 /* ignore close error */
3568 } 3577 }
3578 }
3579 }
3580
3581 /**
3582 * Set the line endings used in the stream returned by {@link Download#getStream()}
3583 * @param sep separator to use
3584 * @throws IllegalArgumentException if sep is neither "\n" nor "\r\n"
3585 */
3586 public void setLineSeparator(String sep) {
3587 if ("\n".equals(sep)) {
3588 prependCr = false;
3589 } else if ("\r\n".equals(sep)) {
3590 prependCr = true;
3591 } else {
3592 throw new IllegalArgumentException("sep must be \n or \r\n");
3569 } 3593 }
3570 } 3594 }
3571 } 3595 }
3572 3596
3573 public static class StripCrLfStream extends FilterOutputStream { 3597 public static class StripCrLfStream extends FilterOutputStream {