working on more data structures

This commit is contained in:
Jörg Prante 2021-04-08 22:36:40 +02:00
parent 5a0fe36e18
commit 8ebb1a8e69
772 changed files with 198255 additions and 145 deletions

202
LICENSE.txt Normal file
View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -28,6 +28,7 @@ subprojects {
apply from: rootProject.file('gradle/ide/idea.gradle')
apply from: rootProject.file('gradle/compile/java.gradle')
apply from: rootProject.file('gradle/test/junit5.gradle')
apply from: rootProject.file('gradle/test/jmh.gradle')
apply from: rootProject.file('gradle/publishing/publication.gradle')
}

View file

@ -0,0 +1,6 @@
dependencies {
api "net.openhft:chronicle-core:2.21ea14"
testImplementation "org.junit.vintage:junit-vintage-engine:5.7.0"
testImplementation "junit:junit:4.13"
testImplementation "net.openhft:affinity:3.21ea0"
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,72 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.bytes.algo.BytesStoreHash;
import net.openhft.chronicle.core.io.AbstractReferenceCounted;
import java.nio.BufferUnderflowException;
public abstract class AbstractBytesStore<B extends BytesStore<B, Underlying>, Underlying>
extends AbstractReferenceCounted
implements BytesStore<B, Underlying> {
protected AbstractBytesStore() {
}
protected AbstractBytesStore(boolean monitored) {
super(monitored);
}
@Override
public int peekUnsignedByte(long offset) throws BufferUnderflowException {
return offset >= readLimit() ? -1 : readUnsignedByte(offset);
}
@Override
public int hashCode() {
return BytesStoreHash.hash32(this);
}
@Override
public long readPosition() {
return 0L;
}
@Override
public long readRemaining() {
return readLimit() - readPosition();
}
@Override
public long writeRemaining() {
return writeLimit() - writePosition();
}
@Override
public long start() {
return 0L;
}
@Override
protected boolean performReleaseInBackground() {
return isDirectMemory();
}
}

View file

@ -0,0 +1,332 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.annotation.Java9;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.UTFDataFormatException;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
@SuppressWarnings("rawtypes")
public enum AppendableUtil {
;
public static void setCharAt( Appendable sb, int index, char ch)
throws IllegalArgumentException, BufferOverflowException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).setCharAt(index, ch);
else if (sb instanceof Bytes)
((Bytes) sb).writeByte(index, ch);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static void parseUtf8( BytesStore bs, StringBuilder sb, boolean utf, int length) throws UTFDataFormatRuntimeException {
BytesInternal.parseUtf8(bs, bs.readPosition(), sb, utf, length);
}
@ForceInline
public static void setLength( Appendable sb, int newLength)
throws BufferUnderflowException, IllegalArgumentException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).setLength(newLength);
else if (sb instanceof Bytes)
((Bytes) sb).readPositionRemaining(0, newLength);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static void append( Appendable sb, double value)
throws IllegalArgumentException, BufferOverflowException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).append(value);
else if (sb instanceof Bytes)
((Bytes) sb).append(value);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static void append( Appendable sb, long value)
throws IllegalArgumentException, BufferOverflowException {
if (sb instanceof StringBuilder)
((StringBuilder) sb).append(value);
else if (sb instanceof Bytes)
((Bytes) sb).append(value);
else
throw new IllegalArgumentException("" + sb.getClass());
}
public static <ACS extends Appendable & CharSequence> void append( ACS sb, String str) {
try {
sb.append(str);
} catch (IOException e) {
throw new AssertionError(e);
}
}
public static void read8bitAndAppend( StreamingDataInput bytes,
StringBuilder appendable,
StopCharsTester tester) {
while (true) {
int c = bytes.readUnsignedByte();
if (tester.isStopChar(c, bytes.peekUnsignedByte()))
return;
appendable.append((char) c);
if (bytes.readRemaining() == 0)
return;
}
}
public static void readUTFAndAppend( StreamingDataInput bytes,
Appendable appendable,
StopCharsTester tester)
throws BufferUnderflowException {
try {
readUtf8AndAppend(bytes, appendable, tester);
} catch (IOException e) {
throw new AssertionError(e);
}
}
public static void readUtf8AndAppend( StreamingDataInput bytes,
Appendable appendable,
StopCharsTester tester)
throws BufferUnderflowException, IOException {
while (true) {
int c = bytes.readUnsignedByte();
if (c >= 128) {
bytes.readSkip(-1);
break;
}
// this is used for array class such as !type byte[]
if (c == '[' && bytes.peekUnsignedByte() == ']') {
appendable.append((char) c);
appendable.append((char) bytes.readUnsignedByte());
if (bytes.readRemaining() == 0)
return;
continue;
}
if (tester.isStopChar(c, bytes.peekUnsignedByte()))
return;
appendable.append((char) c);
if (bytes.readRemaining() == 0)
return;
}
for (int c; (c = bytes.readUnsignedByte()) >= 0; ) {
switch (c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
/* 0xxxxxxx */
if (tester.isStopChar(c, bytes.peekUnsignedByte()))
return;
appendable.append((char) c);
break;
case 12:
case 13: {
/* 110x xxxx 10xx xxxx */
int char2 = bytes.readUnsignedByte();
if ((char2 & 0xC0) != 0x80)
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(char2));
int c2 = (char) (((c & 0x1F) << 6) |
(char2 & 0x3F));
if (tester.isStopChar(c2, bytes.peekUnsignedByte()))
return;
appendable.append((char) c2);
break;
}
case 14: {
/* 1110 xxxx 10xx xxxx 10xx xxxx */
int char2 = bytes.readUnsignedByte();
int char3 = bytes.readUnsignedByte();
if (((char2 & 0xC0) != 0x80))
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(char2));
if ((char3 & 0xC0) != 0x80)
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(char3));
int c3 = (char) (((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
(char3 & 0x3F));
if (tester.isStopChar(c3, bytes.peekUnsignedByte()))
return;
appendable.append((char) c3);
break;
}
default:
/* 10xx xxxx, 1111 xxxx */
throw new UTFDataFormatException(
"malformed input around byte " + Integer.toHexString(c));
}
}
}
public static void parse8bit_SB1( Bytes bytes, StringBuilder sb, int length)
throws BufferUnderflowException {
if (length > bytes.readRemaining())
throw new BufferUnderflowException();
NativeBytesStore nbs = (NativeBytesStore) bytes.bytesStore();
long offset = bytes.readPosition();
int count = BytesInternal.parse8bit_SB1(offset, nbs, sb, length);
bytes.readSkip(count);
}
public static void parse8bit( StreamingDataInput bytes, Appendable appendable, int utflen)
throws BufferUnderflowException, IOException {
if (appendable instanceof StringBuilder) {
final StringBuilder sb = (StringBuilder) appendable;
if (bytes instanceof Bytes && ((Bytes) bytes).bytesStore() instanceof NativeBytesStore) {
parse8bit_SB1((Bytes) bytes, sb, utflen);
} else {
BytesInternal.parse8bit1(bytes, sb, utflen);
}
} else {
BytesInternal.parse8bit1(bytes, appendable, utflen);
}
}
public static <ACS extends Appendable & CharSequence> void append(ACS a, CharSequence cs, long start, long len) {
if (a instanceof StringBuilder) {
if (cs instanceof Bytes)
((StringBuilder) a).append(Bytes.toString(((Bytes) cs), start, len));
else
((StringBuilder) a).append(cs.subSequence(Maths.toInt32(start), Maths.toInt32(len)));
} else if (a instanceof Bytes) {
((Bytes) a).appendUtf8(cs, Maths.toInt32(start), Maths.toInt32(len));
} else {
throw new UnsupportedOperationException();
}
}
public static long findUtf8Length( CharSequence str) throws IndexOutOfBoundsException {
int strlen = str.length();
long utflen = strlen;/* use charAt instead of copying String to char array */
for (int i = 0; i < strlen; i++) {
char c = str.charAt(i);
if (c <= 0x007F) {
continue;
}
if (c <= 0x07FF) {
utflen++;
} else {
utflen += 2;
}
}
return utflen;
}
@Java9
public static long findUtf8Length( byte[] bytes, byte coder) {
long utflen;
if (coder == 0) {
int strlen = bytes.length;
utflen = bytes.length;
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < strlen; i++) {
int b = (bytes[i] & 0xFF);
if (b > 0x007F) {
utflen++;
}
}
} else {
int strlen = bytes.length;
utflen = 0;/* use charAt instead of copying String to char array */
for (int i = 0; i < strlen; i += 2) {
char c = (char) (((bytes[i + 1] & 0xFF) << 8) | (bytes[i] & 0xFF));
if (c <= 0x007F) {
utflen += 1;
continue;
}
if (c <= 0x07FF) {
utflen += 2;
} else {
utflen += 3;
}
}
}
return utflen;
}
@Java9
public static long findUtf8Length( byte[] chars) {
long utflen = 0; /* use charAt instead of copying String to char array */
int strlen = chars.length;
for (int i = 0; i < strlen; i++) {
int c = chars[i] & 0xFF; // unsigned byte
if (c == 0) { // we have hit end of string
break;
}
if (c >= 0xF0) {
utflen += 4;
i += 3;
} else if (c >= 0xE0) {
utflen += 3;
i += 2;
} else if (c >= 0xC0) {
utflen += 2;
i += 1;
} else {
utflen += 1;
}
}
return utflen;
}
public static long findUtf8Length( char[] chars) {
long utflen = chars.length;/* use charAt instead of copying String to char array */
for (char c : chars) {
if (c <= 0x007F) {
continue;
}
if (c <= 0x07FF) {
utflen++;
} else {
utflen += 2;
}
}
return utflen;
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.core.util.AbstractInvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
public class BinaryBytesMethodWriterInvocationHandler extends AbstractInvocationHandler implements BytesMethodWriterInvocationHandler {
private final Function<Method, MethodEncoder> methodToId;
@SuppressWarnings("rawtypes")
private final BytesOut out;
private final Map<Method, MethodEncoder> methodToIdMap = new LinkedHashMap<>();
@SuppressWarnings("rawtypes")
public BinaryBytesMethodWriterInvocationHandler(Function<Method, MethodEncoder> methodToId, BytesOut out) {
super(HashMap::new);
this.methodToId = methodToId;
this.out = out;
}
@Override
protected Object doInvoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
MethodEncoder info = methodToIdMap.computeIfAbsent(method, methodToId);
if (info == null) {
Jvm.warn().on(getClass(), "Unknown method " + method + " ignored");
return null;
}
out.comment(method.getName());
out.writeStopBit(info.messageId());
info.encode(args, out);
return null;
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.bytes;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public interface BinaryWireCode {
// sequence of length 0 - 255 bytes
int BYTES_LENGTH8 = 0x80;
// sequence of length 0 - 2^16-1 bytes
int BYTES_LENGTH16 = 0x81;
// sequence of length 0 - 2^32-1
int BYTES_LENGTH32 = 0x82;
// sequence of length 0 - 255
// public static final int BYTES_LENGTH64 = 0x83;
int FIELD_ANCHOR = 0x87;
int ANCHOR = 0x88;
int UPDATED_ALIAS = 0x89;
// an array of unsigned bytes
int U8_ARRAY = 0x8A;
// public static final int U16_ARRAY = 0x8B;
// public static final int I32_ARRAY = 0x8C;
int I64_ARRAY = 0x8D;
int PADDING32 = 0x8E;
int PADDING = 0x8F;
int FLOAT32 = 0x90;
int FLOAT64 = 0x91;
int FLOAT_STOP_2 = 0x92;
int FLOAT_STOP_4 = 0x94;
int FLOAT_STOP_6 = 0x96;
int FLOAT_SET_LOW_0 = 0x9A;
int FLOAT_SET_LOW_2 = 0x9B;
int FLOAT_SET_LOW_4 = 0x9C;
// 0x98 - 0x9F
int UUID = 0xA0;
int UINT8 = 0xA1;
int UINT16 = 0xA2;
int UINT32 = 0xA3;
int INT8 = 0xA4;
int INT16 = 0xA5;
int INT32 = 0xA6;
int INT64 = 0xA7;
int SET_LOW_INT8 = 0xA8;
int SET_LOW_INT16 = 0xA9;
// public static final int FIXED_5 = 0xAA;
// public static final int FIXED_4 = 0xAB;
// public static final int FIXED_3 = 0xAC;
// public static final int FIXED_2 = 0xAD;
int STOP_BIT = 0xAE;
int INT64_0x = 0xAF;
int FALSE = 0xB0;
int TRUE = 0xB1;
int TIME = 0xB2;
int DATE = 0xB3;
int DATE_TIME = 0xB4;
int ZONED_DATE_TIME = 0xB5;
int TYPE_PREFIX = 0xB6;
int FIELD_NAME_ANY = 0xB7;
int STRING_ANY = 0xB8;
int EVENT_NAME = 0xB9;
int FIELD_NUMBER = 0xBA;
int NULL = 0xBB;
int TYPE_LITERAL = 0xBC;
int EVENT_OBJECT = 0xBD;
int COMMENT = 0xBE;
int HINT = 0xBF;
int FIELD_NAME0 = 0xC0;
// ...
int FIELD_NAME31 = 0xDF;
int STRING_0 = 0xE0;
// ...
int STRING_31 = 0xFF;
String[] STRING_FOR_CODE = _stringForCode(BinaryWireCode.class);
static String[] _stringForCode(Class clazz) {
String[] stringForCode = new String[256];
try {
for ( Field field : clazz.getDeclaredFields()) {
if (field.getType() == int.class)
stringForCode[field.getInt(null)] = field.getName();
else if (field.getType() == byte.class)
stringForCode[field.getByte(null) & 0xFF] = field.getName();
}
for (int i = FIELD_NAME0; i <= FIELD_NAME31; i++)
stringForCode[i] = "FIELD_" + i;
for (int i = STRING_0; i <= STRING_31; i++)
stringForCode[i] = "STRING_" + i;
for (int i = 0; i < stringForCode.length; i++) {
if (stringForCode[i] == null)
if (i <= ' ' || i >= 127)
stringForCode[i] = "Unknown_0x" + Integer.toHexString(i).toUpperCase();
else
stringForCode[i] = "Unknown_" + (char) i;
}
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
return stringForCode;
}
}

View file

@ -0,0 +1,308 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.UnsafeText;
import org.jetbrains.annotations.NotNull;
import java.io.Writer;
import java.math.BigDecimal;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
/**
* Methods to append text to a Bytes. This extends the Appendable interface.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public interface ByteStringAppender<B extends ByteStringAppender<B>> extends StreamingDataOutput<B>, Appendable {
/**
* @return these Bytes as a Writer
*/
default Writer writer() {
return new ByteStringWriter(this);
}
/**
* Append a char in UTF-8
*
* @param ch to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
@Override
default B append(char ch) throws BufferOverflowException {
BytesInternal.appendUtf8Char(this, ch);
return (B) this;
}
/**
* Append a characters in UTF-8
*
* @param cs to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
@Override
default B append( CharSequence cs) throws BufferOverflowException {
if (cs.length() == 0)
return (B) this;
try {
return append(cs, 0, cs.length());
} catch (IndexOutOfBoundsException e) {
throw new AssertionError(e);
}
}
/**
* Append a boolean as T or F
*
* @param flag to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(boolean flag) throws BufferOverflowException {
return append(flag ? 'T' : 'F');
}
/**
* Append an int in decimal
*
* @param value to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(int value) throws BufferOverflowException {
BytesInternal.appendBase10(this, value);
return (B) this;
}
/**
* Append a long in decimal
*
* @param value to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(long value) throws BufferOverflowException {
if (value == (int) value)
BytesInternal.appendBase10(this, (int) value);
else
BytesInternal.appendBase10(this, value);
return (B) this;
}
default B appendBase(long value, int base) throws BufferOverflowException {
BytesInternal.append(this, value, base);
return (B) this;
}
default B appendBase16(long value) throws BufferOverflowException {
BytesInternal.appendBase16(this, value, 1);
return (B) this;
}
default B appendBase16(long value, int minDigits) throws BufferOverflowException {
BytesInternal.appendBase16(this, value, minDigits);
return (B) this;
}
/**
* Append a long in decimal with a given number of decimal places. Print value * 10^-decimalPlaces
*
* @param value to append
* @param decimalPlaces to shift the decimal place.
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B appendDecimal(long value, int decimalPlaces) throws BufferOverflowException {
BytesInternal.appendDecimal(this, value, decimalPlaces);
return (B) this;
}
/**
* Append a float in decimal notation
*
* @param f to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(float f) throws BufferOverflowException {
float f2 = Math.abs(f);
if (f2 > 1e6 || f2 < 1e-3) {
return append(Float.toString(f));
}
int precision = (int) Math.floor(6 - Math.log10(f2));
long tens = Maths.tens(precision);
return append((double) Math.round(f * tens) / tens);
}
/**
* Append a double in decimal notation
*
* @param d to append
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(double d) throws BufferOverflowException {
BytesInternal.append(this, d);
return (B) this;
}
/**
* Append a double in decimal notation to a specific number of decimal places. Trailing zeros are not truncated.
* <p>
* If the number would normally be printed with more decimal places, the number is rounded.
*
* @param d to append
* @param decimalPlaces to always produce
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IORuntimeException if an error occurred while attempting to resize the underlying buffer
*/
default B append(double d, int decimalPlaces) throws BufferOverflowException {
if (decimalPlaces < 0)
throw new IllegalArgumentException();
if (decimalPlaces < 18) {
double d2 = d * Maths.tens(decimalPlaces);
if (d2 < Long.MAX_VALUE && d2 > Long.MIN_VALUE) {
// changed from java.lang.Math.round(d2) as this was shown up to cause latency
long round = d2 > 0.0 ? (long) (d2 + 0.5) : (long) (d2 - 0.5);
if (canWriteDirect(20 + decimalPlaces)) {
long address = addressForWritePosition();
long address2 = UnsafeText.appendBase10d(address, round, decimalPlaces);
writeSkip(address2 - address);
} else {
appendDecimal(round, decimalPlaces);
}
return (B) this;
}
}
return append(d);
}
/**
* Append a portion of a String to the Bytes in UTF-8.
*
* @param cs to copy
* @param start index of the first char inclusive
* @param end index of the last char exclusive.
* @return this
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
@Override
default B append( CharSequence cs, int start, int end)
throws IndexOutOfBoundsException, BufferOverflowException {
BytesInternal.appendUtf8(this, cs, start, end - start);
return (B) this;
}
/**
* Append a String to the Bytes in ISO-8859-1
*
* @param cs to write
* @return this
* @throws BufferOverflowException If the string as too large to write in the capacity available
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
*/
default B append8bit( CharSequence cs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return append8bit(cs, 0, cs.length());
}
default B append8bit( BytesStore bs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return write(bs, 0L, bs.readRemaining());
}
default B append8bit( String cs)
throws BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return append8bit(cs, 0, cs.length());
}
/**
* Append a portion of a String to the Bytes in ISO-8859-1
*
* @param cs to copy
* @param start index of the first char inclusive
* @param end index of the last char exclusive.
* @return this
* @throws BufferOverflowException If the string as too large to write in the capacity available
* @throws BufferUnderflowException if the capacity of the underlying buffer was exceeded
* @throws IndexOutOfBoundsException if the start or the end are not valid for the CharSequence
*/
default B append8bit( CharSequence cs, int start, int end)
throws IllegalArgumentException, BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
if (cs instanceof BytesStore) {
return write((BytesStore) cs, (long) start, end);
}
for (int i = start; i < end; i++) {
char c = cs.charAt(i);
if (c > 255) c = '?';
writeByte((byte) c);
}
return (B) this;
}
default B append8bit( BytesStore bs, long start, long end)
throws IllegalArgumentException, BufferOverflowException, BufferUnderflowException, IndexOutOfBoundsException {
return write(bs, start, end);
}
default B appendDateMillis(long dateInMillis) {
BytesInternal.appendDateMillis(this, dateInMillis);
return (B) this;
}
default B appendTimeMillis(long timeOfDayInMillis) {
BytesInternal.appendTimeMillis(this, timeOfDayInMillis % 86400_000L);
return (B) this;
}
default B append( BigDecimal bigDecimal) {
append(bigDecimal.toString());
return (B) this;
}
}

View file

@ -0,0 +1,252 @@
/*
* Copyright 2016-2020 chronicle.software
*
* https://chronicle.software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.bytes;
import net.openhft.chronicle.core.Maths;
import net.openhft.chronicle.core.annotation.ForceInline;
import net.openhft.chronicle.core.io.IORuntimeException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Reader;
import java.math.BigDecimal;
import java.nio.BufferUnderflowException;
/**
* Supports parsing bytes as text. You can parse them as special or white space terminated text.
*/
interface ByteStringParser<B extends ByteStringParser<B>> extends StreamingDataInput<B> {
/**
* Access these bytes as an ISO-8859-1 encoded Reader
*
* @return as a Reader
*/
default Reader reader() {
return new ByteStringReader(this);
}
/**
* Return true or false, or null if it could not be detected
* as true or false. Case is not important
* <p>
* <p>false: f, false, n, no, 0
* <p>
* <p>true: t, true, y, yes, 1
*
* @param tester to detect the end of the text.
* @return true, false, or null if neither.
*/
default Boolean parseBoolean( StopCharTester tester) {
return BytesInternal.parseBoolean(this, tester);
}
default Boolean parseBoolean() {
return BytesInternal.parseBoolean(this, StopCharTesters.NON_ALPHA_DIGIT);
}
/**
* parse text with UTF-8 decoding as character terminated.
*
* @param stopCharTester to check if the end has been reached.
* @return the text as a String.
*/
@ForceInline
default String parseUtf8( StopCharTester stopCharTester) {
return BytesInternal.parseUtf8(this, stopCharTester);
}
@Deprecated(/* to be removed in x.22 */)
default String parseUTF( StopCharTester stopCharTester) {
return parseUtf8(stopCharTester);
}
/**
* parse text with UTF-8 decoding as character terminated.
*
* @param buffer to populate
* @param stopCharTester to check if the end has been reached.
*/
@ForceInline
default void parseUtf8( Appendable buffer, StopCharTester stopCharTester) throws BufferUnderflowException {
BytesInternal.parseUtf8(this, buffer, stopCharTester);
}
@Deprecated(/* to be removed in x.22 */)
default void parseUTF( Appendable buffer, StopCharTester stopCharTester) throws BufferUnderflowException {
parseUtf8(buffer, stopCharTester);
}
/**
* parse text with UTF-8 decoding as one or two character terminated.
*
* @param buffer to populate
* @param stopCharsTester to check if the end has been reached.
*/
@ForceInline
default void parseUtf8( Appendable buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException, IORuntimeException {
BytesInternal.parseUtf8(this, buffer, stopCharsTester);
}
@Deprecated(/* to be removed in x.22 */)
default void parseUTF( Appendable buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException, IORuntimeException {
parseUtf8(buffer, stopCharsTester);
}
/**
* parse text with ISO-8859-1 decoding as character terminated.
*
* @param buffer to populate
* @param stopCharTester to check if the end has been reached.
*/
@SuppressWarnings("rawtypes")
@ForceInline
default void parse8bit(Appendable buffer, StopCharTester stopCharTester)
throws BufferUnderflowException {
if (buffer instanceof StringBuilder)
BytesInternal.parse8bit(this, (StringBuilder) buffer, stopCharTester);
else
BytesInternal.parse8bit(this, (Bytes) buffer, stopCharTester);
}
/**
* parse text with ISO-8859-1 decoding as character terminated.
*
* @param stopCharTester to check if the end has been reached.
*/
default String parse8bit( StopCharTester stopCharTester)
throws BufferUnderflowException {
return BytesInternal.parse8bit(this, stopCharTester);
}
/**
* parse text with ISO-8859-1 decoding as character terminated.
*
* @param buffer to populate
* @param stopCharsTester to check if the end has been reached.
*/
@SuppressWarnings("rawtypes")
@ForceInline
default void parse8bit(Appendable buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException {
if (buffer instanceof StringBuilder)
BytesInternal.parse8bit(this, (StringBuilder) buffer, stopCharsTester);
else
BytesInternal.parse8bit(this, (Bytes) buffer, stopCharsTester);
}
@SuppressWarnings("rawtypes")
default void parse8bit(Bytes buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException {
BytesInternal.parse8bit(this, buffer, stopCharsTester);
}
default void parse8bit(StringBuilder buffer, StopCharsTester stopCharsTester)
throws BufferUnderflowException {
BytesInternal.parse8bit(this, buffer, stopCharsTester);
}
/**
* parse text as an int. The terminating character is consumed.
*
* @return an int.
*/
@ForceInline
default int parseInt() throws BufferUnderflowException {
return Maths.toInt32(BytesInternal.parseLong(this));
}
/**
* parse text as a long integer. The terminating character is consumed.
*
* @return a long.
*/
@ForceInline
default long parseLong() throws BufferUnderflowException {
return BytesInternal.parseLong(this);
}
/**
* parse text as a float decimal. The terminating character is consumed.
* <p>
* The number of decimal places can be retrieved with lastDecimalPlaces()
*
* @return a float.
*/
default float parseFloat() throws BufferUnderflowException {
return (float) BytesInternal.parseDouble(this);
}
/**
* parse text as a double decimal. The terminating character is consumed.
* <p>
* The number of decimal places can be retrieved with lastDecimalPlaces()