Browse Source

Update aXMLRPC to 1.12.0

pull/554/head
TacoTheDank 4 years ago
parent
commit
e756cf05ae
  1. 1
      app/build.gradle
  2. 16
      app/src/main/java/de/timroes/axmlrpc/Call.java
  3. 15
      app/src/main/java/de/timroes/axmlrpc/ResponseParser.java
  4. 35
      app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java
  5. 2
      app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java
  6. 4
      app/src/main/java/de/timroes/axmlrpc/XMLUtil.java
  7. 17
      app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java
  8. 4
      app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java
  9. 8
      app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java
  10. 60
      app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java
  11. 7
      app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java
  12. 10
      app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java
  13. 12
      app/src/main/java/de/timroes/base64/Base64.java

1
app/build.gradle

@ -93,6 +93,7 @@ dependencies {
implementation 'com.github.aegnor:rencode-java:cb628e824e' implementation 'com.github.aegnor:rencode-java:cb628e824e'
implementation 'org.apache.openjpa:openjpa-lib:3.1.1' implementation 'org.apache.openjpa:openjpa-lib:3.1.1'
implementation 'net.iharder:base64:2.3.9' implementation 'net.iharder:base64:2.3.9'
//implementation 'de.timroes:aXMLRPC:1.12.0'
implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') { implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') {
transitive = true transitive = true
} }

16
app/src/main/java/de/timroes/axmlrpc/Call.java

@ -16,13 +16,14 @@ public class Call {
private String method; private String method;
private Object[] params; private Object[] params;
private final SerializerHandler serializerHandler;
/** /**
* Create a new method call with the given name and no parameters. * Create a new method call with the given name and no parameters.
* @param method The method to be called. * @param method The method to be called.
*/ */
public Call(String method) { public Call(SerializerHandler serializerHandler, String method) {
this(method, null); this(serializerHandler, method, null);
} }
/** /**
@ -30,9 +31,10 @@ public class Call {
* @param method The method to be called. * @param method The method to be called.
* @param params An array of parameters for the method. * @param params An array of parameters for the method.
*/ */
public Call(String method, Object[] params) { public Call(SerializerHandler serializerHandler, String method, Object[] params) {
this.method = method; this.method = method;
this.params = params; this.params = params;
this.serializerHandler = serializerHandler;
} }
/** /**
@ -57,11 +59,11 @@ public class Call {
methodCall.addChildren(methodName); methodCall.addChildren(methodName);
if(params != null && params.length > 0) { if(params != null && params.length > 0) {
XmlElement params = new XmlElement(XMLRPCClient.PARAMS); XmlElement callParams = new XmlElement(XMLRPCClient.PARAMS);
methodCall.addChildren(params); methodCall.addChildren(callParams);
for(Object o : this.params) { for(Object o : this.params) {
params.addChildren(getXMLParam(o)); callParams.addChildren(getXMLParam(o));
} }
} }
@ -79,7 +81,7 @@ public class Call {
XmlElement param = new XmlElement(XMLRPCClient.PARAM); XmlElement param = new XmlElement(XMLRPCClient.PARAM);
XmlElement value = new XmlElement(XMLRPCClient.VALUE); XmlElement value = new XmlElement(XMLRPCClient.VALUE);
param.addChildren(value); param.addChildren(value);
value.addChildren(SerializerHandler.getDefault().serialize(o)); value.addChildren(serializerHandler.serialize(o));
return param; return param;
} }

15
app/src/main/java/de/timroes/axmlrpc/ResponseParser.java

@ -16,7 +16,7 @@ import org.xmlpull.v1.XmlPullParserFactory;
* *
* @author Tim Roes * @author Tim Roes
*/ */
class ResponseParser { public class ResponseParser {
private static final String FAULT_CODE = "faultCode"; private static final String FAULT_CODE = "faultCode";
private static final String FAULT_STRING = "faultString"; private static final String FAULT_STRING = "faultString";
@ -71,13 +71,13 @@ class ResponseParser {
pullParser.nextTag(); // TAG_VALUE (<value>) pullParser.nextTag(); // TAG_VALUE (<value>)
// no parser.require() here since its called in XMLRPCSerializer.deserialize() below // no parser.require() here since its called in XMLRPCSerializer.deserialize() below
// deserialize result // deserialize result
Object obj = SerializerHandler.getDefault().deserialize(pullParser); Object obj = SerializerHandler.deserialize(pullParser);
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
return obj; return obj;
} else if (tag.equals(XMLRPCClient.FAULT)) { } else if (tag.equals(XMLRPCClient.FAULT)) {
// fault response // fault response
pullParser.nextTag(); // TAG_VALUE (<value>) pullParser.nextTag(); // TAG_VALUE (<value>)
Map<String, Object> map = (Map<String, Object>) SerializerHandler.getDefault().deserialize(pullParser); Map<String, Object> map = (Map<String, Object>) SerializerHandler.deserialize(pullParser);
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
//Check that required tags are in the response //Check that required tags are in the response
@ -92,12 +92,11 @@ class ResponseParser {
} catch (XmlPullParserException ex) { } catch (XmlPullParserException ex) {
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
throw new XMLRPCException("Error parsing response.", ex); throw new XMLRPCException("Error parsing response.", ex);
} catch(XMLRPCServerException e) {
throw e;
} catch (Exception ex) { } catch (Exception ex) {
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
if(ex instanceof XMLRPCServerException) throw new XMLRPCException("Error getting result from server.", ex);
throw (XMLRPCServerException)ex;
else
throw new XMLRPCException("Error getting result from server.", ex);
} }
} }
} }

35
app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java

@ -127,6 +127,11 @@ public class XMLRPCClient {
*/ */
public static final int FLAGS_NO_STRING_ENCODE = 0x1000; public static final int FLAGS_NO_STRING_ENCODE = 0x1000;
/**
* Accepts response containing eg: <dateTime.iso8601/>
*/
public static final int FLAGS_ACCEPT_NULL_DATES = 0x4000;
/** /**
* This flag should be used if the server is an apache ws xmlrpc server. * This flag should be used if the server is an apache ws xmlrpc server.
* This will set some flags, so that the not standard conform behavior * This will set some flags, so that the not standard conform behavior
@ -140,28 +145,30 @@ public class XMLRPCClient {
private final int flags; private final int flags;
private DefaultHttpClient httpclient; private DefaultHttpClient httpclient;
private String url; private String url;
private Map<Long,Caller> backgroundCalls = new ConcurrentHashMap<Long, Caller>(); private Map<Long,Caller> backgroundCalls = new ConcurrentHashMap<Long, Caller>();
private ResponseParser responseParser; private ResponseParser responseParser;
private final SerializerHandler serializerHandler;
/** /**
* Create a new XMLRPC client for the given URL. * Create a new XMLRPC client for the given URL.
* *
* @param httpclient The already-initialized Apache HttpClient to use for connection. * @param httpclient The already-initialized Apache HttpClient to use for connection.
* @param url The URL to send the requests to. * @param url The URL to send the requests to.
* @param flags A combination of flags to be set. * @param flags A combination of flags to be set.
*/ */
public XMLRPCClient(DefaultHttpClient httpclient, String url, int flags) { public XMLRPCClient(DefaultHttpClient httpclient, String url, int flags) {
SerializerHandler.initialize(flags); this.serializerHandler = new SerializerHandler(flags);
this.httpclient = httpclient; this.httpclient = httpclient;
this.url = url; this.url = url;
this.flags = flags; this.flags = flags;
// Create a parser for the http responses. // Create a parser for the http responses.
responseParser = new ResponseParser(); responseParser = new ResponseParser();
@ -260,7 +267,7 @@ public class XMLRPCClient {
throw new XMLRPCRuntimeException("Method name must only contain A-Z a-z . : _ / "); throw new XMLRPCRuntimeException("Method name must only contain A-Z a-z . : _ / ");
} }
return new Call(method, params); return new Call(serializerHandler, method, params);
} }
@ -368,7 +375,7 @@ public class XMLRPCClient {
try { try {
Call c = createCall(methodName, params); Call c = createCall(methodName, params);
// Prepare POST request // Prepare POST request
// FIXME: where creating a new HttpPost so calling #cancel isn't going to do anything // FIXME: where creating a new HttpPost so calling #cancel isn't going to do anything
HttpPost post = new HttpPost(url); HttpPost post = new HttpPost(url);
@ -377,10 +384,10 @@ public class XMLRPCClient {
StringEntity entity = new StringEntity(c.getXML(), HTTP.UTF_8); StringEntity entity = new StringEntity(c.getXML(), HTTP.UTF_8);
entity.setContentType(TYPE_XML); entity.setContentType(TYPE_XML);
post.setEntity(entity); post.setEntity(entity);
HttpResponse response = httpclient.execute(post); HttpResponse response = httpclient.execute(post);
int statusCode = response.getStatusLine().getStatusCode(); int statusCode = response.getStatusLine().getStatusCode();
InputStream istream; InputStream istream;
// If status code was 401 or 403 throw exception or if appropriate // If status code was 401 or 403 throw exception or if appropriate
@ -406,7 +413,7 @@ public class XMLRPCClient {
|| statusCode == HttpURLConnection.HTTP_MOVED_TEMP) { || statusCode == HttpURLConnection.HTTP_MOVED_TEMP) {
// ... do either a foward // ... do either a foward
if(isFlagSet(FLAGS_FORWARD)) { if(isFlagSet(FLAGS_FORWARD)) {
boolean temporaryForward = (statusCode == HttpURLConnection.HTTP_MOVED_TEMP); boolean temporaryForward = statusCode == HttpURLConnection.HTTP_MOVED_TEMP;
// Get new location from header field. // Get new location from header field.
String newLocation = response.getFirstHeader("Location").getValue(); String newLocation = response.getFirstHeader("Location").getValue();
@ -440,10 +447,8 @@ public class XMLRPCClient {
} }
// Check for strict parameters // Check for strict parameters
if(isFlagSet(FLAGS_STRICT)) { if(isFlagSet(FLAGS_STRICT) && !response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) {
if(!response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) {
throw new XMLRPCException("The Content-Type of the response must be text/xml."); throw new XMLRPCException("The Content-Type of the response must be text/xml.");
}
} }
return responseParser.parse(istream, entity); return responseParser.parse(istream, entity);
@ -462,9 +467,9 @@ public class XMLRPCClient {
} }
} }
} }
public static class CancelException extends Exception { public static class CancelException extends Exception {
private static final long serialVersionUID = 9125122307255855136L; private static final long serialVersionUID = 9125122307255855136L;
} }
@ -475,5 +480,5 @@ public class XMLRPCClient {
public UnauthorizdException(int statusCode) { this.statusCode = statusCode; } public UnauthorizdException(int statusCode) { this.statusCode = statusCode; }
public int getStatusCode() { return statusCode; } public int getStatusCode() { return statusCode; }
} }
} }

2
app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java

@ -8,7 +8,7 @@ package de.timroes.axmlrpc;
*/ */
public class XMLRPCServerException extends XMLRPCException { public class XMLRPCServerException extends XMLRPCException {
private int errornr; private final int errornr;
public XMLRPCServerException(String ex, int errnr) { public XMLRPCServerException(String ex, int errnr) {
super(ex); super(ex);

4
app/src/main/java/de/timroes/axmlrpc/XMLUtil.java

@ -9,6 +9,8 @@ import de.timroes.axmlrpc.xmlcreator.XmlElement;
*/ */
public class XMLUtil { public class XMLUtil {
private XMLUtil() {}
/** /**
* Creates an xml tag with a given type and content. * Creates an xml tag with a given type and content.
* *
@ -22,4 +24,4 @@ public class XMLUtil {
return xml; return xml;
} }
} }

17
app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java

@ -3,6 +3,7 @@ package de.timroes.axmlrpc.serializer;
import de.timroes.axmlrpc.XMLRPCException; import de.timroes.axmlrpc.XMLRPCException;
import de.timroes.axmlrpc.XMLRPCRuntimeException; import de.timroes.axmlrpc.XMLRPCRuntimeException;
import de.timroes.axmlrpc.xmlcreator.XmlElement; import de.timroes.axmlrpc.xmlcreator.XmlElement;
import java.util.Arrays;
/** /**
* *
@ -12,10 +13,20 @@ public class ArraySerializer implements Serializer {
private static final String ARRAY_DATA = "data"; private static final String ARRAY_DATA = "data";
private static final String ARRAY_VALUE = "value"; private static final String ARRAY_VALUE = "value";
private final SerializerHandler serializerHandler;
public ArraySerializer(SerializerHandler serializerHandler){
this.serializerHandler = serializerHandler;
}
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
Iterable<?> iter = (Iterable<?>)object; Iterable<?> iter;
if ( object instanceof Iterable<?>){
iter = (Iterable<?>)object;
} else {
iter = Arrays.asList((Object[]) object);
}
XmlElement array = new XmlElement(SerializerHandler.TYPE_ARRAY); XmlElement array = new XmlElement(SerializerHandler.TYPE_ARRAY);
XmlElement data = new XmlElement(ARRAY_DATA); XmlElement data = new XmlElement(ARRAY_DATA);
array.addChildren(data); array.addChildren(data);
@ -25,7 +36,7 @@ public class ArraySerializer implements Serializer {
XmlElement e; XmlElement e;
for(Object obj : iter) { for(Object obj : iter) {
e = new XmlElement(ARRAY_VALUE); e = new XmlElement(ARRAY_VALUE);
e.addChildren(SerializerHandler.getDefault().serialize(obj)); e.addChildren(serializerHandler.serialize(obj));
data.addChildren(e); data.addChildren(e);
} }
@ -37,4 +48,4 @@ public class ArraySerializer implements Serializer {
} }
} }

4
app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java

@ -11,7 +11,7 @@ public class BooleanSerializer implements Serializer {
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_BOOLEAN, return XMLUtil.makeXmlTag(SerializerHandler.TYPE_BOOLEAN,
((Boolean)object == true) ? "1" : "0"); (Boolean) object ? "1" : "0");
} }
} }

8
app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java

@ -10,9 +10,15 @@ import java.text.SimpleDateFormat;
*/ */
public class DateTimeSerializer implements Serializer { public class DateTimeSerializer implements Serializer {
public static final String DATETIME_FORMAT = "yyyyMMdd'T'HH:mm:ss"; public static final String DATETIME_FORMAT = "yyyyMMdd'T'HHmmss";
public static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat(DATETIME_FORMAT); public static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat(DATETIME_FORMAT);
public final boolean accepts_null_input;
public DateTimeSerializer(boolean accepts_null_input) {
this.accepts_null_input = accepts_null_input;
}
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_DATETIME, return XMLUtil.makeXmlTag(SerializerHandler.TYPE_DATETIME,
DATE_FORMATER.format(object)); DATE_FORMATER.format(object));

60
app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java

@ -2,7 +2,6 @@ package de.timroes.axmlrpc.serializer;
import de.timroes.axmlrpc.XMLRPCClient; import de.timroes.axmlrpc.XMLRPCClient;
import de.timroes.axmlrpc.XMLRPCException; import de.timroes.axmlrpc.XMLRPCException;
import de.timroes.axmlrpc.XMLRPCRuntimeException;
import de.timroes.axmlrpc.xmlcreator.XmlElement; import de.timroes.axmlrpc.xmlcreator.XmlElement;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -60,54 +59,29 @@ public class SerializerHandler {
public static final String TYPE_BASE64 = "base64"; public static final String TYPE_BASE64 = "base64";
public static final String TYPE_NULL = "nil"; public static final String TYPE_NULL = "nil";
private static SerializerHandler instance;
/**
* Initialize the serialization handler. This method must be called before
* the get method returns any object.
*
* @param flags The flags that has been set in the XMLRPCClient.
* @see XMLRPCClient
*/
public static void initialize(int flags) {
instance = new SerializerHandler(flags);
}
/**
* Return the instance of the SerializerHandler.
* It must have been initialized with initialize() before.
*
* @return The instance of the SerializerHandler.
*/
public static SerializerHandler getDefault() {
if(instance == null) {
throw new XMLRPCRuntimeException("The SerializerHandler has not been initialized.");
}
return instance;
}
private StringSerializer string; private StringSerializer string;
private BooleanSerializer bool = new BooleanSerializer(); private BooleanSerializer bool = new BooleanSerializer();
private IntSerializer integer = new IntSerializer(); private IntSerializer integer = new IntSerializer();
private LongSerializer long8 = new LongSerializer(); private LongSerializer long8 = new LongSerializer();
private StructSerializer struct = new StructSerializer(); private StructSerializer struct;
private DoubleSerializer floating = new DoubleSerializer(); private DoubleSerializer floating = new DoubleSerializer();
private DateTimeSerializer datetime = new DateTimeSerializer(); private DateTimeSerializer datetime;
private ArraySerializer array = new ArraySerializer(); public static boolean accepts_null_input;
public SerializerHandler(boolean accepts_null_input) {
SerializerHandler.accepts_null_input = accepts_null_input;
}
private ArraySerializer array;
private Base64Serializer base64 = new Base64Serializer(); private Base64Serializer base64 = new Base64Serializer();
private NullSerializer nil = new NullSerializer(); private NullSerializer nil = new NullSerializer();
private int flags; private int flags;
/** public SerializerHandler(int flags) {
* Generates the SerializerHandler.
* This method can only called from within the class (the initialize method).
*
* @param flags The flags to use.
*/
private SerializerHandler(int flags) {
this.flags = flags; this.flags = flags;
string = new StringSerializer((flags & XMLRPCClient.FLAGS_NO_STRING_ENCODE) == 0); string = new StringSerializer((flags & XMLRPCClient.FLAGS_NO_STRING_ENCODE) == 0);
struct = new StructSerializer(this);
array = new ArraySerializer(this);
datetime = new DateTimeSerializer((flags & XMLRPCClient.FLAGS_ACCEPT_NULL_DATES) != 0);
} }
/** /**
@ -152,8 +126,12 @@ public class SerializerHandler {
obj = parser.nextText(); obj = parser.nextText();
} else } else
if (typeNodeName.equals(TYPE_DATE_TIME_ISO8601)) { if (typeNodeName.equals(TYPE_DATE_TIME_ISO8601)) {
dateFormat.setCalendar(cal); dateFormat.setCalendar(cal);
String value = parser.nextText(); String value = parser.nextText();
if (accepts_null_input && (value==null || value.trim().length()==0)) {
return null;
}
try { try {
obj = dateFormat.parseObject(value); obj = dateFormat.parseObject(value);
} catch (ParseException e) { } catch (ParseException e) {
@ -232,7 +210,7 @@ public class SerializerHandler {
*/ */
public XmlElement serialize(Object object) throws XMLRPCException { public XmlElement serialize(Object object) throws XMLRPCException {
Serializer s = null; Serializer s;
if((flags & XMLRPCClient.FLAGS_NIL) != 0 && object == null) { if((flags & XMLRPCClient.FLAGS_NIL) != 0 && object == null) {
s = nil; s = nil;
@ -277,7 +255,7 @@ public class SerializerHandler {
s = base64; s = base64;
} else if(object instanceof Byte[]) { } else if(object instanceof Byte[]) {
s = base64; s = base64;
} else if(object instanceof Iterable<?>) { } else if(object instanceof Iterable<?> || object instanceof Object[]) {
s = array; s = array;
} else { } else {
throw new XMLRPCException("No serializer found for type '" throw new XMLRPCException("No serializer found for type '"
@ -288,4 +266,4 @@ public class SerializerHandler {
} }
} }

7
app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java

@ -19,9 +19,12 @@ public class StringSerializer implements Serializer {
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
String content = object.toString(); String content = object.toString();
if(encodeStrings) { if(encodeStrings) {
content = content.replaceAll("&", "&amp;").replaceAll("<", "&lt;"); content = content
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll("]]>", "]]&gt;");
} }
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_STRING, content); return XMLUtil.makeXmlTag(SerializerHandler.TYPE_STRING, content);
} }
} }

10
app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java

@ -15,6 +15,12 @@ public class StructSerializer implements Serializer {
private static final String STRUCT_NAME = "name"; private static final String STRUCT_NAME = "name";
private static final String STRUCT_VALUE = "value"; private static final String STRUCT_VALUE = "value";
private final SerializerHandler serializerHandler;
public StructSerializer(SerializerHandler serializerHandler) {
this.serializerHandler = serializerHandler;
}
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
XmlElement struct = new XmlElement(SerializerHandler.TYPE_STRUCT); XmlElement struct = new XmlElement(SerializerHandler.TYPE_STRUCT);
@ -33,7 +39,7 @@ public class StructSerializer implements Serializer {
name = new XmlElement(STRUCT_NAME); name = new XmlElement(STRUCT_NAME);
value = new XmlElement(STRUCT_VALUE); value = new XmlElement(STRUCT_VALUE);
name.setContent(member.getKey()); name.setContent(member.getKey());
value.addChildren(SerializerHandler.getDefault().serialize(member.getValue())); value.addChildren(serializerHandler.serialize(member.getValue()));
entry.addChildren(name); entry.addChildren(name);
entry.addChildren(value); entry.addChildren(value);
struct.addChildren(entry); struct.addChildren(entry);
@ -46,4 +52,4 @@ public class StructSerializer implements Serializer {
return struct; return struct;
} }
} }

12
app/src/main/java/de/timroes/base64/Base64.java

@ -14,6 +14,8 @@ public class Base64 {
private static final HashMap<Character,Byte> map = new HashMap<Character, Byte>(); private static final HashMap<Character,Byte> map = new HashMap<Character, Byte>();
private Base64() {}
static { static {
for(int i = 0; i < code.length; i++) { for(int i = 0; i < code.length; i++) {
map.put(code[i], (byte)i); map.put(code[i], (byte)i);
@ -44,10 +46,10 @@ public class Base64 {
int outi = 0; int outi = 0;
int b1, b2, b3, b4; int b1, b2, b3, b4;
for(int i = 0; i < input.length; i+=4) { for(int i = 0; i < input.length; i+=4) {
b1 = (map.get(input[i]) - 1); b1 = map.get(input[i]) - 1;
b2 = (map.get(input[i+1]) - 1); b2 = map.get(input[i+1]) - 1;
b3 = (map.get(input[i+2]) - 1); b3 = map.get(input[i+2]) - 1;
b4 = (map.get(input[i+3]) - 1); b4 = map.get(input[i+3]) - 1;
out[outi++] = (byte)(b1 << 2 | b2 >>> 4); out[outi++] = (byte)(b1 << 2 | b2 >>> 4);
out[outi++] = (byte)((b2 & 0x0F) << 4 | b3 >>> 2); out[outi++] = (byte)((b2 & 0x0F) << 4 | b3 >>> 2);
out[outi++] = (byte)((b3 & 0x03) << 6 | (b4 & 0x3F)); out[outi++] = (byte)((b3 & 0x03) << 6 | (b4 & 0x3F));
@ -158,4 +160,4 @@ public class Base64 {
return out; return out;
} }
} }

Loading…
Cancel
Save