package org.properssl.sslcertx.mariadb.jdbc.internal.common.query.parameters;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
* Helper class for serializing query parameters
*/
public class ParameterWriter {
static final byte[] BINARY_INTRODUCER = {'_','b','i','n','a','r','y',' ','\''};
static final Charset UTF8 = Charset.forName("UTF-8");
static final byte[] QUOTE = {'\''};
private static void writeBytesEscaped(OutputStream out, byte[] bytes, int count, boolean noBackslashEscapes)
throws IOException{
if (noBackslashEscapes) {
for (int i = 0; i < count; i++) {
byte b = bytes[i];
switch(b) {
case '\'':
out.write('\'');
out.write(b);
break;
default:
out.write(b);
}
}
} else {
for (int i = 0; i < count; i++) {
byte b = bytes[i];
switch(b) {
case '\\':
case '\'':
case '"':
case 0:
out.write('\\');
out.write(b);
break;
default:
out.write(b);
}
}
}
}
private static void writeBytesEscaped(OutputStream out, byte[] bytes, boolean noBackslashEscapes) throws IOException{
writeBytesEscaped(out, bytes, bytes.length, noBackslashEscapes);
}
public static void write(OutputStream out, byte[] bytes, boolean noBackslashEscapes) throws IOException{
out.write(BINARY_INTRODUCER);
writeBytesEscaped(out, bytes, noBackslashEscapes);
out.write(QUOTE);
}
public static void write(OutputStream out, String s, boolean noBackslashEscapes) throws IOException {
byte[] bytes = s.getBytes(UTF8);
out.write(QUOTE);
writeBytesEscaped(out,bytes, noBackslashEscapes);
out.write(QUOTE);
}
public static void write(OutputStream out, InputStream is, boolean noBackslashEscapes, boolean isText) throws IOException{
if (isText) {
out.write(QUOTE);
} else {
out.write(BINARY_INTRODUCER);
}
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) >= 0) {
writeBytesEscaped(out, buffer, len, noBackslashEscapes);
}
out.write(QUOTE);
}
public static void write(OutputStream out, InputStream is, long length, boolean noBackslashEscapes, boolean isText) throws IOException{
if (isText) {
out.write(QUOTE);
} else {
out.write(BINARY_INTRODUCER);
}
byte[] buffer = new byte[1024];
long bytesLeft = length;
int len;
for (;;) {
int bytesToRead = (int)Math.min(bytesLeft, buffer.length);
if(bytesToRead == 0)
break;
len = is.read(buffer,0, bytesToRead);
if (len <= 0)
break;
writeBytesEscaped(out, buffer, len, noBackslashEscapes);
bytesLeft -= len;
}
out.write(QUOTE);
}
public static void write(OutputStream out, java.io.Reader reader, boolean noBackslashEscapes) throws IOException {
out.write(QUOTE);
char[] buffer = new char[1024];
int len;
while ((len = reader.read(buffer)) >= 0) {
writeBytesEscaped(out, new String(buffer,0, len).getBytes(UTF8), noBackslashEscapes);
}
out.write(QUOTE);
}
public static void write(OutputStream out, java.io.Reader reader, long length, boolean noBackslashEscapes)
throws IOException{
out.write(QUOTE);
char[] buffer = new char[1024];
long charsLeft = length;
int len;
for (;;) {
int charsToRead = (int)Math.min(charsLeft, buffer.length);
if(charsToRead == 0)
break;
len = reader.read(buffer,0, charsToRead);
if (len <= 0)
break;
byte[] bytes = new String(buffer, 0, len).getBytes(UTF8);
writeBytesEscaped(out, bytes, bytes.length, noBackslashEscapes);
charsLeft -= len;
}
out.write(QUOTE);
}
public static void write(OutputStream out, int i) throws IOException{
out.write(String.valueOf(i).getBytes());
}
public static void write(OutputStream out, long l) throws IOException {
out.write(String.valueOf(l).getBytes());
}
public static void write(OutputStream out, double d) throws IOException {
out.write(String.valueOf(d).getBytes());
}
public static void write(OutputStream out, BigDecimal bd) throws IOException {
out.write(bd.toPlainString().getBytes());
}
public static void writeDate(OutputStream out, java.util.Date date, Calendar calendar) throws IOException {
out.write(QUOTE);
String dateString;
if (calendar != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setCalendar(calendar);
dateString = sdf.format(date);
} else {
dateString = date.toString();
}
out.write(dateString.getBytes());
out.write(QUOTE);
}
static void formatMicroseconds(OutputStream out, int microseconds, boolean writeFractionalSeconds) throws IOException {
if (microseconds == 0 || !writeFractionalSeconds)
return;
out.write('.');
int factor = 100000;
while(microseconds > 0) {
int dig = microseconds / factor;
out.write('0' + dig);
microseconds -= dig*factor;
factor /= 10;
}
}
public static void writeTimestamp(OutputStream out, Timestamp ts, Calendar calendar, boolean writeFractionalSeconds)
throws IOException {
out.write(QUOTE);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (calendar != null) {
sdf.setCalendar(calendar);
}
String dateString = sdf.format(ts);
out.write(dateString.getBytes());
formatMicroseconds(out, ts.getNanos() / 1000, writeFractionalSeconds);
out.write(QUOTE);
}
public static void writeTime(OutputStream out, Time time, Calendar calendar, boolean writeFractionalSeconds)
throws IOException{
out.write(QUOTE);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
if (calendar != null) {
sdf.setCalendar(calendar);
}
String dateString = sdf.format(time);
out.write(dateString.getBytes());
int microseconds = (int)(time.getTime()%1000) * 1000;
formatMicroseconds(out, microseconds, writeFractionalSeconds);
out.write(QUOTE);
}
public static void writeObject(OutputStream out, Object o, boolean noBackslashEscapes)throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
write(out,baos.toByteArray(), noBackslashEscapes);
}
}