mirror of
https://github.com/diamante0018/ServerList.git
synced 2025-03-12 11:06:56 +00:00
Init
This commit is contained in:
commit
0c2a642ed4
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# Eclipse m2e generated files
|
||||
# Eclipse Core
|
||||
.project
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
18
nb-configuration.xml
Normal file
18
nb-configuration.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<netbeans.checkstyle.format>true</netbeans.checkstyle.format>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
25
pom.xml
Normal file
25
pom.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.diamante.serverlist</groupId>
|
||||
<artifactId>ServerList</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<configuration>
|
||||
<configLocation>config/sun_checks.xml</configLocation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<exec.mainClass>com.diamante.serverlist.Main</exec.mainClass>
|
||||
</properties>
|
||||
</project>
|
56
src/main/java/com/diamante/serverlist/Main.java
Normal file
56
src/main/java/com/diamante/serverlist/Main.java
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Diamante
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.diamante.serverlist;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diamante
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static final AtomicBoolean running = new AtomicBoolean(true);
|
||||
|
||||
private final MasterServer server;
|
||||
|
||||
public Main() {
|
||||
server = new MasterServer();
|
||||
}
|
||||
|
||||
public MasterServer getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Running shutdown hook");
|
||||
running.compareAndSet(true, false);
|
||||
}
|
||||
});
|
||||
|
||||
var main = new Main();
|
||||
|
||||
while (running.get() && main.getServer().isValid()) {
|
||||
main.getServer().await();
|
||||
}
|
||||
|
||||
main.getServer().stop();
|
||||
}
|
||||
}
|
175
src/main/java/com/diamante/serverlist/MasterServer.java
Normal file
175
src/main/java/com/diamante/serverlist/MasterServer.java
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Diamante
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.diamante.serverlist;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diamante
|
||||
*/
|
||||
public class MasterServer {
|
||||
|
||||
public static final int PORT = 27017;
|
||||
|
||||
private ServerSocket socket;
|
||||
|
||||
private boolean valid;
|
||||
|
||||
private final ServerList serverList;
|
||||
|
||||
public MasterServer() {
|
||||
serverList = new ServerList();
|
||||
|
||||
try {
|
||||
socket = new ServerSocket(PORT);
|
||||
valid = true;
|
||||
} catch (IOException ex) {
|
||||
System.err.println(String.format("Socket creation on port %d failed", PORT));
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePacket(Socket from, ByteArrayOutputStream packetData) {
|
||||
|
||||
if (packetData.size() < Utils.PACKET_MIN_LEN) {
|
||||
System.out.println(String.format("handlePacket: packetData.size() is less than %d bytes", Utils.PACKET_MIN_LEN));
|
||||
return;
|
||||
}
|
||||
|
||||
var blob = packetData.toByteArray();
|
||||
|
||||
var magicLE = Arrays.copyOfRange(blob, 0, 4);
|
||||
var magicBE = Utils.longSwap(magicLE);
|
||||
|
||||
var versionLE = Arrays.copyOfRange(blob, 4, 8);
|
||||
var versionBE = Utils.longSwap(versionLE);
|
||||
|
||||
if (Utils.isServerMagic(magicBE)) {
|
||||
System.out.println("handlePacket: magic is of type server");
|
||||
|
||||
if (packetData.size() < 10) {
|
||||
System.out.println("handlePacket: server packet is less than 10 bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
var portLE = Arrays.copyOfRange(blob, 8, 10);
|
||||
var portBE = Utils.shortSwap(portLE);
|
||||
System.out.println(String.format("handlePacket: server %s has net_port %d", from.getInetAddress(), portBE));
|
||||
|
||||
var server = new Server(from.getInetAddress(), portBE, versionBE);
|
||||
serverList.addServer(server);
|
||||
|
||||
} else if (Utils.isClientMagic(magicBE)) {
|
||||
System.out.println("handlePacket: magic is of type client");
|
||||
|
||||
serverList.removeInactive();
|
||||
var toSend = serverList.createResponse(versionBE);
|
||||
|
||||
try {
|
||||
var out = new DataOutputStream(from.getOutputStream());
|
||||
out.write(toSend);
|
||||
|
||||
// Clean things up
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
System.err.println("handlePacket: IOException in DataOutputStream(from.getOutputStream())");
|
||||
}
|
||||
} else {
|
||||
System.out.println("handlePacket: magic is not recognized");
|
||||
}
|
||||
}
|
||||
|
||||
public void await() {
|
||||
Socket worker;
|
||||
InputStream in;
|
||||
|
||||
try {
|
||||
worker = socket.accept();
|
||||
System.out.println("Accepted a connection");
|
||||
} catch (IOException ex) {
|
||||
System.err.println("await: IOException in socket.accept()");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
in = worker.getInputStream();
|
||||
} catch (IOException ex) {
|
||||
System.err.println("await: IOException in worker.getInputStream()");
|
||||
return;
|
||||
}
|
||||
|
||||
var bytes = new byte[Utils.BUFFER_SIZE];
|
||||
var out = new ByteArrayOutputStream();
|
||||
|
||||
int count;
|
||||
|
||||
try {
|
||||
while ((count = in.read(bytes)) > 0) {
|
||||
out.write(bytes, 0, count);
|
||||
|
||||
// The client seems to cause this loop to never end
|
||||
// We cut connection after PACKET_MIN_LEN is read
|
||||
// Server does not cause problems
|
||||
if (count >= Utils.PACKET_MIN_LEN) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
System.err.println("await: IOException in in.read(bytes)");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println(String.format("await: received %d", out.size()));
|
||||
handlePacket(worker, out);
|
||||
|
||||
// Clean things up
|
||||
try {
|
||||
worker.close();
|
||||
out.close();
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
System.err.println("await: IOException while cleaning up");
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
// Can happen if multiple instances are launched
|
||||
if (socket == null || socket.isClosed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException ex) {
|
||||
System.err.println("stop: IOException in socket.close()");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
}
|
108
src/main/java/com/diamante/serverlist/Server.java
Normal file
108
src/main/java/com/diamante/serverlist/Server.java
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Diamante
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.diamante.serverlist;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diamante
|
||||
*/
|
||||
public class Server {
|
||||
|
||||
private InetAddress address;
|
||||
|
||||
private Short netPort;
|
||||
|
||||
private Long time;
|
||||
|
||||
private Integer version;
|
||||
|
||||
public Server(InetAddress address, Short netPort, Integer version) {
|
||||
this.address = address;
|
||||
this.netPort = netPort;
|
||||
this.version = version;
|
||||
|
||||
this.time = System.currentTimeMillis() / 1000L;
|
||||
}
|
||||
|
||||
public InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public short getNetPort(){
|
||||
return netPort;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void updateTime() {
|
||||
this.time = System.currentTimeMillis() / 1000L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Server other = (Server) obj;
|
||||
if (!Objects.equals(this.address, other.address)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(this.netPort, other.netPort)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(this.version, other.version)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 71 * hash + Objects.hashCode(this.address);
|
||||
hash = 71 * hash + Objects.hashCode(this.netPort);
|
||||
hash = 71 * hash + Objects.hashCode(this.version);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s:%d", this.getAddress().toString(), this.netPort);
|
||||
}
|
||||
}
|
133
src/main/java/com/diamante/serverlist/ServerList.java
Normal file
133
src/main/java/com/diamante/serverlist/ServerList.java
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Diamante
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.diamante.serverlist;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diamante
|
||||
*/
|
||||
public class ServerList {
|
||||
|
||||
private final Set<Server> serverList;
|
||||
|
||||
public ServerList() {
|
||||
serverList = Collections.synchronizedSet(new HashSet<>());
|
||||
}
|
||||
|
||||
public boolean isServerRegistered(Server server) {
|
||||
synchronized (serverList) {
|
||||
var it = serverList.iterator(); // Must be in the synchronized block
|
||||
while (it.hasNext()) {
|
||||
var other = it.next();
|
||||
if (server.equals(other)) {
|
||||
// Update the time so we don't accidentally remove the server
|
||||
other.updateTime();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addServer(Server server) {
|
||||
|
||||
if (!isServerRegistered(server)) {
|
||||
serverList.add(server);
|
||||
}
|
||||
|
||||
System.out.println(String.format("addServer: Tried to add server %s", server.toString()));
|
||||
}
|
||||
|
||||
public void removeInactive() {
|
||||
synchronized (serverList) {
|
||||
var it = serverList.iterator();
|
||||
var time = System.currentTimeMillis() / 1000L;
|
||||
|
||||
while (it.hasNext()) {
|
||||
var server = it.next();
|
||||
if (time - server.getTime() > 60) {
|
||||
System.out.println(String.format("Removing server %s because of inactivity", server.getAddress().toString()));
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The first 4 bytes will contain the numbers of servers we are going to
|
||||
* send in LE Then we have 4 bytes for the IP address in LE Finally 2 bytes
|
||||
* for the net_port in LE Repeat for each server
|
||||
*
|
||||
* @param version the version of the client
|
||||
* @return the raw bytes to send to the client
|
||||
*/
|
||||
public byte[] createResponse(int version) {
|
||||
var builder = new ByteArrayOutputStream();
|
||||
|
||||
// We need to swap everything to LE
|
||||
var sizeBE = serverList.size();
|
||||
var sizeLE = Utils.longSwap(sizeBE);
|
||||
|
||||
try {
|
||||
builder.write(sizeLE);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
System.err.println("createResponse: IOException in builder.write(sizeLE)");
|
||||
}
|
||||
|
||||
synchronized (serverList) {
|
||||
var it = serverList.iterator(); // Must be in the synchronized block
|
||||
while (it.hasNext()) {
|
||||
var server = it.next();
|
||||
// Let's make sure we send the client only servers on the same version
|
||||
if (server.getVersion() == version) {
|
||||
try {
|
||||
// Let's flip the bytes of this one too
|
||||
var ipBE = server.getAddress().getAddress();
|
||||
Utils.swapByteArray(ipBE);
|
||||
|
||||
// And the port too of course
|
||||
var portBE = server.getNetPort();
|
||||
var portLE = Utils.shortSwap(portBE);
|
||||
|
||||
builder.write(ipBE);
|
||||
builder.write(portLE);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
System.err.println("createResponse: IOException while writing server data)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// I forgot why I do this
|
||||
var byteBuffer = ByteBuffer.allocate(builder.size());
|
||||
byteBuffer.clear();
|
||||
byteBuffer.put(builder.toByteArray());
|
||||
byteBuffer.flip();
|
||||
return byteBuffer.array();
|
||||
}
|
||||
}
|
132
src/main/java/com/diamante/serverlist/Utils.java
Normal file
132
src/main/java/com/diamante/serverlist/Utils.java
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Diamante
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.diamante.serverlist;
|
||||
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ReadOnlyBufferException;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diamante
|
||||
*/
|
||||
public class Utils {
|
||||
|
||||
public static final int BUFFER_SIZE = 512;
|
||||
|
||||
public static final int PACKET_MIN_LEN = 8;
|
||||
public static final int PACKET_CLIENT_LEN = 8;
|
||||
public static final int PACKET_SERVERT_LEN = 10;
|
||||
|
||||
// (Warning: Remember to take into account endianness)
|
||||
// 'HELP'
|
||||
public static final int SERVER_MAGIC = 1212501072;
|
||||
// 'THEM'
|
||||
public static final int CLIENT_MAGIC = 1414022477;
|
||||
|
||||
public static boolean isServerMagic(int magic) {
|
||||
return magic == SERVER_MAGIC;
|
||||
}
|
||||
|
||||
public static boolean isClientMagic(int magic) {
|
||||
return magic == CLIENT_MAGIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips the array of in around
|
||||
*
|
||||
* @param in array of in. Length must be multiple of 4
|
||||
*/
|
||||
public static void swapByteArray(byte[] in) {
|
||||
assert in.length % 4 == 0;
|
||||
|
||||
for (var i = 0; i < in.length; i += 4) {
|
||||
// swap 0 and 3
|
||||
byte tmp = in[i];
|
||||
in[i] = in[i + 3];
|
||||
in[i + 3] = tmp;
|
||||
// swap 1 and 2
|
||||
byte tmp2 = in[i + 1];
|
||||
in[i + 1] = in[i + 2];
|
||||
in[i + 2] = tmp2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param in raw bytes in LE order
|
||||
* @return integer in BE
|
||||
*/
|
||||
public static int longSwap(byte[] in) {
|
||||
assert in.length == 4;
|
||||
|
||||
var buffer = ByteBuffer.allocate(4);
|
||||
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
try {
|
||||
buffer.put(in);
|
||||
return buffer.getInt(0);
|
||||
}
|
||||
catch (BufferOverflowException | ReadOnlyBufferException ex) {
|
||||
System.err.println("longSwap: BufferOverflowException or ReadOnlyBufferException");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param in
|
||||
* @return raw bytes in LE order
|
||||
*/
|
||||
public static byte[] longSwap(int in) {
|
||||
var buffer = ByteBuffer.allocate(4);
|
||||
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putInt(in);
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in raw bytes in LE order
|
||||
* @return short in BE
|
||||
*/
|
||||
public static short shortSwap(byte[] in) {
|
||||
assert in.length == 2;
|
||||
|
||||
var buffer = ByteBuffer.allocate(2);
|
||||
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
try {
|
||||
buffer.put(in);
|
||||
return buffer.getShort(0);
|
||||
}
|
||||
catch (BufferOverflowException | ReadOnlyBufferException ex) {
|
||||
System.err.println("longSwap: BufferOverflowException or ReadOnlyBufferException");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param in
|
||||
* @return raw bytes in LE order
|
||||
*/
|
||||
public static byte[] shortSwap(short in) {
|
||||
var buffer = ByteBuffer.allocate(2);
|
||||
buffer.order(java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putShort(in);
|
||||
return buffer.array();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user