{"id":19765861,"url":"https://github.com/openhft/chronicle-wire","last_synced_at":"2026-03-04T08:08:02.193Z","repository":{"id":25862008,"uuid":"29301872","full_name":"OpenHFT/Chronicle-Wire","owner":"OpenHFT","description":"A Low Garbage Java Serialisation Library that supports multiple formats","archived":false,"fork":false,"pushed_at":"2026-01-27T01:03:37.000Z","size":20785,"stargazers_count":573,"open_issues_count":41,"forks_count":136,"subscribers_count":38,"default_branch":"ea","last_synced_at":"2026-01-27T01:43:18.783Z","etag":null,"topics":["binary","csv","java","json","serialization","yaml"],"latest_commit_sha":null,"homepage":"http://chronicle.software","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenHFT.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2015-01-15T14:47:29.000Z","updated_at":"2026-01-26T12:19:45.000Z","dependencies_parsed_at":"2023-01-16T22:16:08.648Z","dependency_job_id":"1ff76ed8-df62-446d-8f3d-e143c757b91f","html_url":"https://github.com/OpenHFT/Chronicle-Wire","commit_stats":null,"previous_names":[],"tags_count":578,"template":false,"template_full_name":null,"purl":"pkg:github/OpenHFT/Chronicle-Wire","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Wire","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Wire/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Wire/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Wire/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenHFT","download_url":"https://codeload.github.com/OpenHFT/Chronicle-Wire/tar.gz/refs/heads/ea","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Wire/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28853195,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T15:15:36.453Z","status":"ssl_error","status_checked_at":"2026-01-28T15:15:13.020Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary","csv","java","json","serialization","yaml"],"created_at":"2024-11-12T04:19:45.021Z","updated_at":"2026-01-28T22:01:54.148Z","avatar_url":"https://github.com/OpenHFT.png","language":"Java","readme":"= Chronicle Wire\nChronicle Software\n:pp: ++\n:css-signature: demo\n:toc: macro\n:toclevels: 2\n:icons: font\n:sectnums:\n:source-highlighter: rouge\n\nimage:https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-wire/badge.svg[link=https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-wire]\nimage:https://javadoc.io/badge2/net.openhft/chronicle-wire/javadoc.svg[link=\"https://www.javadoc.io/doc/net.openhft/chronicle-wire/latest/index.html\"]\nimage:https://img.shields.io/github/license/OpenHFT/Chronicle-Wire[GitHub License]\nimage:https://img.shields.io/badge/release%20notes-subscribe-brightgreen[link=\"https://chronicle.software/release-notes/\"]\nimage:https://sonarcloud.io/api/project_badges/measure?project=OpenHFT_Chronicle-Wire\u0026metric=alert_status[link=\"https://sonarcloud.io/dashboard?id=OpenHFT_Chronicle-Wire\"]\n\nimage::images/Wire_line.png[width=20%]\n\ntoc::[]\n\n== Introduction\n\nChronicle Wire is a high-performance, zero-GC serialisation library built on top of the Chronicle stack.\nIt abstracts the underlying wire format, letting you use human readable text or compact binary interchangeably while retaining a common API.\nTypical use cases include configuration files, persistence of in-memory state, and extremely fast IPC between JVMs.\n\n== Key Features\n\n* Multiple wire formats (YAML, JSON, CSV, binary variants)\n* Schema evolution with optional field handling\n* Low-latency, low-allocation serialisation of `Marshallable` POJOs\n* Automatic conversion between formats\n* Integration with other Chronicle components === Why are these concerns conflated?\n\nOften you want to use these interchangeably.\n\n* Configuration includes aliased type information.\nThis supports easy extension by adding new classes/versions, and cross-platform using type aliasing.\n* By supporting types, a configuration file can bootstrap itself.\nYou control how the configuration file is decoded.\nSee link:src/test/resources/docs/qe_cfg.yaml[example Queue Enterprise config].\n* To send the configuration of a server to a client, or from a client to a server.\n* To store the configuration of a data store in its header.\n* In configuration, to be able to create any object or component.\n* Save a configuration after you have changed it.\n* To be able to share data in memory between processes in a thread-safe manner.\n\n=== Features\n\nChronicle Wire supports a separation of describing what data you want to store and retrieve, and how it should be rendered/parsed.\nChronicle Wire handles a variety of formatting options, for a wide range of formats.\n\nA key aim of Chronicle Wire is to support schema changes.\nIt should make reasonable attempts to handle:\n\n* optional fields\n* fields in a different order\n* fields that the consumer doesn't expect; optionally parsing them, or ignoring them\n* more or less data than expected; in field-less formats\n* reading a different type to the one written\n* updating fixed-length fields, automatically where possible using a `bound` data structure\n* dynamic updates of Enums or objects passed-by-name\n\nChronicle Wire will also be efficient where any, or all, of the following points are true:\n\n* fields are in the order expected\n* fields are the type expected\n* fields names/numbers are not used\n* self-describing types are not needed\n* random access of data values is supported\n\nChronicle Wire is designed to make it easy to convert from one wire format to another.\nFor example, you can use fixed-width binary data in memory for performance, and variable-width or text over the network.\nDifferent TCP connections could use different formats.\n\nChronicle Wire also supports hybrid wire formats.\nFor example, you can have one format embedded in another.\n\n== Support\n\nThis library requires Java 8. Support for `C{pp}`, `ruby` and `python` is available in Chronicle Queue Enterprise.\n\n== Text Formats\n\nThe text formats include:\n\n* `YAML` - subset of mapping structures included\n* `JSON` - superset to support serialization\n* `CSV` - superset to support serialization\n* `XML` - planned\n\nOptions include:\n\n* field names (for example, JSON), or field numbers (for example, FIX)\n* optional fields with default values that can be dropped\n* zero-copy access to fields - planned\n* thread-safe operations in text - planned\n\nTo support wire format discovery, the first byte should be in the `ASCII` range; adding an `ASCII` whitespace if needed.\n\n== Binary Formats\n\nThe binary formats include:\n\n* binary YAML\n* typed data without fields\n* raw untyped fieldless data\n* Trivially Copyable Objects (lowest latency)\n\nOptions for Binary format:\n\n* field names or field numbers\n* variable width\n* optional fields with a default value can be dropped\n* fixed width data with zero copy support\n* thread-safe operations\n\nNote: Chronicle Wire supports debug/transparent combinations like self-describing data with zero copy support.\n\nTo support wire format discovery, the first bytes should have the top bit set.\n\n== Getting Started\n\nAdd the dependency to your project.\n\n.Maven\n[source,xml]\n----\n\u003cdependency\u003e\n    \u003cgroupId\u003enet.openhft\u003c/groupId\u003e\n    \u003cartifactId\u003echronicle-wire\u003c/artifactId\u003e\n    \u003cversion\u003eREPLACE_WITH_VERSION\u003c/version\u003e\n\u003c/dependency\u003e\n----\n\n.Gradle\n[source,groovy]\n----\nimplementation 'net.openhft:chronicle-wire:REPLACE_WITH_VERSION'\n----\n\n.Simple Example\n[source,java,opts=novalidate]\n----\nBytes\u003c?\u003e bytes = Bytes.allocateElasticOnHeap();\nWire wire = WireType.TEXT.apply(bytes);\n\nwire.write(\"message\").text(\"Hello World\");\nSystem.out.println(bytes.toString());\n----\n\n== WireType Overview\n\n|===============\n|WireType |Enum |Human Readable |Self Describing |Size/ Latency |NOTE\n|TextWire |TEXT |YES |NO |More compact than JSON |YAML based\n|BinaryWire |BINARY |NO |YES |Better performance than YAML (half the latency) |Use this when only using Binary\n|BinaryWire |BINARY_LIGHT |NO |YES |Better performance than YAML (half the latency) |Use this when only using Binary, same as BINARY\n|BinaryWire |FIELDLESS_BINARY |NO |YES |Better performance than YAML (half the latency) |\n|JSONWire |JSON |YES |NO |Microsecond latencies |Uses a 4-bit length prefix\n|JSONWire |JSON_ONLY |YES |NO |Microsecond latencies |Uses new lines between messages\n|YamlWire |YAML |YES |NO |More compact than JSON |YAML based\n|YamlWire |YAML_ONLY |YES |NO |More compact than JSON |YAML based\n|RawWire |RAW |NO |YES |More compact than BinaryWire |Writes just the data without the metadata\n|CSVWire |CSV |YES |NO |More compact than JSON |YAML based\n|ReadAnyWire |READ_ANY |- |- |Can be either |Reads any format\n|===============\n\n== Using Wire\n\n=== link:https://github.com/OpenHFT/Chronicle-Wire/blob/ea/demo/src/main/java/run/chronicle/wire/demo/Example1.java[Simple use case]\n\nFirst you need to have a buffer to write to.\nThis can be a `byte[]`, a `ByteBuffer`, off-heap memory, or even an address and length that you have obtained from some other library.\n\n[source,java,opts=novalidate]\n----\n// Bytes which wraps a byte[]\nBytes\u003cbyte[]\u003e bytes = Bytes.allocateElasticOnHeap();\n// or\n// Bytes which wraps a ByteBuffer which is resized as needed.\nBytes\u003cByteBuffer\u003e bytes = Bytes.elasticByteBuffer();\n----\n\nNow you can choose which format you are using.\nAs the wire formats are themselves unbuffered, you can use them with the same buffer, but in general using one wire format is easier.\n\n[source,java,opts=novalidate]\n----\nWire wire = new TextWire(bytes);\n// or\nWireType wireType = WireType.TEXT;\nWire wireB = wireType.apply(bytes);\n// or\nBytes\u003c?\u003e bytes2 = Bytes.allocateElasticOnHeap();\nWire wire2 = new BinaryWire(bytes2);\n// or\nBytes\u003c?\u003e bytes3 = Bytes.allocateElasticOnHeap();\nWire wire3 = new RawWire(bytes3);\n----\n\nSo now you can write to the wire with a simple document.\n\n[source,java,opts=novalidate]\n----\nwire.write(\"message\").text(\"Hello World\")\n      .write(\"number\").int64(1234567890L)\n      .write(\"code\").asEnum(TimeUnit.SECONDS)\n      .write(\"price\").float64(10.50);\n\nSystem.out.println(bytes);\n----\n\nprints\n\n[source,yaml]\n----\nmessage: Hello World\nnumber: 1234567890\ncode: SECONDS\nprice: 10.5\n----\n\n[source,java,opts=novalidate]\n----\n// The same code for BinaryWire\nwire2.write(\"message\").text(\"Hello World\")\n        .write(\"number\").int64(1234567890L)\n        .write(\"code\").asEnum(TimeUnit.SECONDS)\n        .write(\"price\").float64(10.50);\n\nSystem.out.println(bytes2.toHexString());\n----\n\nprints\n\n[source,text]\n----\n00000000 c7 6d 65 73 73 61 67 65  eb 48 65 6c 6c 6f 20 57 ·message ·Hello W\n00000010 6f 72 6c 64 c6 6e 75 6d  62 65 72 a6 d2 02 96 49 orld·num ber····I\n00000020 c4 63 6f 64 65 e7 53 45  43 4f 4e 44 53 c5 70 72 ·code·SE CONDS·pr\n00000030 69 63 65 90 00 00 28 41                          ice···(A\n----\n\nUsing `RawWire` strips away all the meta data to reduce the size of the message, and improves speed.\nThe down-side is that we cannot easily see what the message contains.\n\n[source,java,opts=novalidate]\n----\n// The same code for RawWire\nwire3.write(\"message\").text(\"Hello World\")\n        .write(\"number\").int64(1234567890L)\n        .write(\"code\").asEnum(TimeUnit.SECONDS)\n        .write(\"price\").float64(10.50);\n\nSystem.out.println(bytes3.toHexString());\n----\n\nprints in `RawWire`.\n\n[source,text]\n----\n00000000 0b 48 65 6c 6c 6f 20 57  6f 72 6c 64 d2 02 96 49 ·Hello W orld···I\n00000010 00 00 00 00 07 53 45 43  4f 4e 44 53 00 00 00 00 ·····SEC ONDS····\n00000020 00 00 25 40                                      ··%@\n----\n\n// For more examples see https://github.com/OpenHFT/Chronicle-Wire/blob/master/README-Chapter1.md[Examples Chapter1]\n=== link:https://github.com/OpenHFT/Chronicle-Wire/blob/ea/demo/src/main/java/run/chronicle/wire/demo/Example2.java[Simple example with a data type]\n\nThis example is much the same as the previous section, with the code required wrapped in a method.\nSee Section \"The code for the class Data\" for the code for Data.\n\n[source,java,opts=novalidate]\n----\n// Bytes which wraps a ByteBuffer which is resized as needed.\nBytes\u003cByteBuffer\u003e bytes = Bytes.elasticByteBuffer();\n\nWire wire = new TextWire(bytes);\n\nData data = new Data(\"Hello World\", 1234567890L, TimeUnit.NANOSECONDS, 10.50);\ndata.writeMarshallable(wire);\nSystem.out.println(bytes);\n\nData data2= new Data();\ndata2.readMarshallable(wire);\nSystem.out.println(data2);\n----\n\nprints\n\n[source,yaml]\n----\nmessage: Hello World\nnumber: 1234567890\ncode: NANOSECONDS\nprice: 10.5\n----\n\n[source,text]\n----\nData{message='Hello World', number=1234567890, timeUnit=NANOSECONDS, price=10.5}\n----\n\nTo write in binary instead\n\n[source,java,opts=novalidate]\n----\nBytes\u003cByteBuffer\u003e bytes2 = Bytes.elasticByteBuffer();\nWire wire2 = new BinaryWire(bytes2);\n\ndata.writeMarshallable(wire2);\nSystem.out.println(bytes2.toHexString());\n\nData data3= new Data();\ndata3.readMarshallable(wire2);\nSystem.out.println(data3);\n----\n\nprints\n\n[source,text]\n----\n00000000 c7 6d 65 73 73 61 67 65  eb 48 65 6c 6c 6f 20 57 ·message ·Hello W\n00000010 6f 72 6c 64 c6 6e 75 6d  62 65 72 a6 d2 02 96 49 orld·num ber····I\n00000020 c8 74 69 6d 65 55 6e 69  74 eb 4e 41 4e 4f 53 45 ·timeUni t·NANOSE\n00000030 43 4f 4e 44 53 c5 70 72  69 63 65 90 00 00 28 41 CONDS·pr ice···(A\n\nData{message='Hello World', number=1234567890, timeUnit=NANOSECONDS, price=10.5}\n----\n\n=== link:https://github.com/OpenHFT/Chronicle-Wire/blob/ea/demo/src/main/java/run/chronicle/wire/demo/Example3.java[Simple example with a nested data type]\n\nIn this example the data is marshalled as a nested data structure.\n\n[source,java,opts=novalidate]\n----\n\n// Bytes which wraps a byte[] which is resized as needed\nBytes\u003c?\u003e bytes = Bytes.allocateElasticOnHeap();\n\nWire wire = new TextWire(bytes);\n\nData data = new Data(\"Hello World\", 1234567890L, TimeUnit.NANOSECONDS, 10.50);\nwire.write(\"mydata\").marshallable(data);\nSystem.out.println(bytes);\n\nData data2= new Data();\nwire.read(\"mydata\").marshallable(data2);\nSystem.out.println(data2);\n----\n\nprints\n\n[source,yaml]\n----\nmydata: {\n  message: Hello World,\n  number: 1234567890,\n  timeUnit: NANOSECONDS,\n  price: 10.5\n}\n----\n\n[source,text]\n----\nData{message='Hello World', number=1234567890, timeUnit=NANOSECONDS, price=10.5}\n----\n\nTo write in binary instead\n\n[source,java,opts=novalidate]\n----\nBytes\u003c?\u003e bytes2 = new HexDumpBytes();\nWire wire2 = new BinaryWire(bytes2);\n\nwire2.write(\"mydata\").marshallable(data);\nSystem.out.println(bytes2.toHexString());\n\nData data3= new Data();\nwire2.read(\"mydata\").marshallable(data3);\nSystem.out.println(data3);\n----\n\nprints\n\n[source,text]\n----\nc6 6d 79 64 61 74 61                            # mydata\n80 40                                           # Data\nc7 6d 65 73 73 61 67 65                         # message\neb 48 65 6c 6c 6f 20 57 6f 72 6c 64             # Hello World\nc6 6e 75 6d 62 65 72                            # number\na6 d2 02 96 49                                  # 1234567890\nc8 74 69 6d 65 55 6e 69 74                      # timeUnit\neb 4e 41 4e 4f 53 45 43 4f 4e 44 53             # NANOSECONDS\nc5 70 72 69 63 65 90 00 00 28 41                # price\n\nData{message='Hello World', number=1234567890, timeUnit=NANOSECONDS, price=10.5}\n----\n\n=== link:https://github.com/OpenHFT/Chronicle-Wire/blob/ea/demo/src/main/java/run/chronicle/wire/demo/Example4.java[Simple example with a data type with a type]\n\nIn this example, the type is encoded with the data.\nInstead of showing the entire package name which will almost certainly not work on any other platform, an alias for the type is used.\nIt also means the message is shorter and faster.\n\n[source,java,opts=novalidate]\n----\nWire wire = new TextWire(Bytes.allocateElasticOnHeap());\n\nClassAliasPool.CLASS_ALIASES.addAlias(Data.class);\n\nData data = new Data(\"Hello World\", 1234567890L, TimeUnit.NANOSECONDS, 10.50);\nwire.write(\"mydata\").object(data);\nSystem.out.println(wire);\n\nData data2= wire.read(\"mydata\").object(Data.class);\nSystem.out.println(data2);\n----\n\nprints\n\n[source,yaml]\n----\nmydata: !Data {\n  message: Hello World,\n  number: 1234567890,\n  timeUnit: NANOSECONDS,\n  price: 10.5\n}\n----\n\n[source,text]\n----\nData{message='Hello World', number=1234567890, timeUnit=NANOSECONDS, price=10.5}\n----\n\nTo write in binary instead\n\n[source,java,opts=novalidate]\n----\nWire wire2 = new TextWire(Bytes.allocateElasticOnHeap());\n\nwire2.write(\"mydata\").object(data);\nSystem.out.println(wire2.bytes().toHexString());\n\nData data3 = wire2.read(\"mydata\").object(Data.class);\nSystem.out.println(data3);\n----\n\nprints\n\n[source,text]\n----\nc6 6d 79 64 61 74 61                            # mydata\nb6 04 44 61 74 61                               # Data\n80 40                                           # Data\nc7 6d 65 73 73 61 67 65                         # message\neb 48 65 6c 6c 6f 20 57 6f 72 6c 64             # Hello World\nc6 6e 75 6d 62 65 72                            # number\na6 d2 02 96 49                                  # 1234567890\nc8 74 69 6d 65 55 6e 69 74                      # timeUnit\neb 4e 41 4e 4f 53 45 43 4f 4e 44 53             # NANOSECONDS\nc5 70 72 69 63 65 90 00 00 28 41                # price\n\nData{message='Hello World', number=1234567890, timeUnit=NANOSECONDS, price=10.5}\n----\n\n=== link:https://github.com/OpenHFT/Chronicle-Wire/blob/ea/demo/src/main/java/run/chronicle/wire/demo/Example6.java[Write a message with a sequence of records]\n\n[source,java,opts=novalidate]\n----\n// Bytes which wraps a ByteBuffer which is resized as needed\nBytes\u003cByteBuffer\u003e bytes = Bytes.elasticByteBuffer();\n\nWire wire = new TextWire(bytes);\n\nClassAliasPool.CLASS_ALIASES.addAlias(Data.class);\n\nData[] data = {\n        new Data(\"Hello World\", 98765, TimeUnit.HOURS, 1.5),\n        new Data(\"G'Day All\", 1212121, TimeUnit.MINUTES, 12.34),\n        new Data(\"Howyall\", 1234567890L, TimeUnit.SECONDS, 1000)\n};\nwire.writeDocument(false, w -\u003e w.write(\"mydata\")\n        .sequence(v -\u003e Stream.of(data).forEach(v::object)));\n\nSystem.out.println(Wires.fromSizePrefixedBlobs(bytes));\n\nList\u003cData\u003e dataList = new ArrayList\u003c\u003e();\nwire.readDocument(null, w -\u003e w.read(\"mydata\")\n        .sequence(dataList, (l, v) -\u003e {\n            while (v.hasNextSequenceItem())\n                l.add(v.object(Data.class));\n       }));\n\ndataList.forEach(System.out::println);\n----\n\nprints\n\n[source,yaml]\n----\n--- !!data\nmydata: [\n  !Data {\n    message: Hello World,\n    number: 98765,\n    timeUnit: HOURS,\n    price: 1.5\n},\n  !Data {\n    message: G'Day All,\n    number: 1212121,\n    timeUnit: MINUTES,\n    price: 12.34\n},\n  !Data {\n    message: Howyall,\n    number: 1234567890,\n    timeUnit: SECONDS,\n    price: 1E3\n}\n]\n----\n\n[source,text]\n----\nData{message='Hello World', number=98765, timeUnit=HOURS, price=1.5}\nData{message='G'Day All', number=1212121, timeUnit=MINUTES, price=12.34}\nData{message='Howyall', number=1234567890, timeUnit=SECONDS, price=1000.0}\n----\n\nTo write in binary instead\n\n[source,java,opts=novalidate]\n----\nBytes\u003cByteBuffer\u003e bytes2 = Bytes.elasticByteBuffer();\nWire wire2 = new BinaryWire(bytes2);\n\nwire2.writeDocument(false, w -\u003e w.write(\"mydata\")\n        .sequence(v -\u003e Stream.of(data).forEach(v::object)));\nSystem.out.println(Wires.fromSizePrefixedBlobs(bytes2));\n\nList\u003cData\u003e dataList2 = new ArrayList\u003c\u003e();\nwire2.readDocument(null, w -\u003e w.read(\"mydata\")\n        .sequence(dataList2, (l, v) -\u003e {\n            while (v.hasNextSequenceItem())\n                l.add(v.object(Data.class));\n        }));\n\ndataList2.forEach(System.out::println);\n----\n\nprints\n\n[source,yaml]\n----\n--- !!data #binary\nmydata: [\n  !Data {\n    message: Hello World,\n    number: !int 98765,\n    timeUnit: HOURS,\n    price: 1.5\n},\n  !Data {\n    message: G'Day All,\n    number: 1212121,\n    timeUnit: MINUTES,\n    price: 12.34\n},\n  !Data {\n    message: Howyall,\n    number: !int 1234567890,\n    timeUnit: SECONDS,\n    price: !int 1000\n}\n]\n----\n\n[source,text]\n----\nData{message='Hello World', number=98765, timeUnit=HOURS, price=1.5}\nData{message='G'Day All', number=1212121, timeUnit=MINUTES, price=12.34}\nData{message='Howyall', number=1234567890, timeUnit=SECONDS, price=1000.0}\n----\n\n=== link:https://github.com/OpenHFT/Chronicle-Wire/blob/ea/demo/src/main/java/run/chronicle/wire/demo/Example7.java[Using the `ClassAliasPool`]\n\nThis example shows how to pass your classes to `ClassAliasPool.CLASS_ALIASES.addAlias(Class\u003c?\u003e... classes)`, to create alias names for them so that you can refer to them without using the complete name of their packages.\n\n[source,java,opts=novalidate]\n----\n// Create two classes Data1 and Data2 and add only the Data1.class to alias pool.\nstatic {\n        ClassAliasPool.CLASS_ALIASES.addAlias(Data1.class);\n}\n\nprivate static class Data1 extends SelfDescribingMarshallable {\n    String name;\n    int age;\n    String address;\n}\n\nprivate static class Data2 extends SelfDescribingMarshallable {\n    String name;\n    int age;\n    String address;\n}\n\n// Create instances of Data1 and Data2\nData1 data1 = new Data1();\ndata1.name = \"James\";\ndata1.age = 20;\ndata1.address = \"12 Kingston, London\";\n\nData2 data2 = new Data2();\ndata2.name = \"James\";\ndata2.age = 20;\ndata2.address = \"12 Kingston, London\";\n----\n\nPrinting out data1 and data2, you will see that the alias name is printed out for data1 but data2 appears with complete package name.\n\n[source,jave]\n----\nSystem.out.println(data1);\nSystem.out.println(data2);\n----\n\nprints:\n\n[source,text]\n----\n!Data1 {\n  name: James,\n  age: 20,\n  address: \"12 Kingston, London\"\n}\n\n!run.chronicle.wire.demo.Example7$Data2 {\n  name: James,\n  age: 20,\n  address: \"12 Kingston, London\"\n}\n----\n\nCreate configuration files cfg1.yaml and cfg2.yaml.\nSee how the classes' names appear differently in yaml files for classes with alias name and without alias name.\nFor Data1 object alias name is used in the yaml file (cfg1.yaml).\nData2 object should be loaded from a yaml file with the complete name of class (including package name) otherwise you will receive an Exception.\n\n.cfg1.yaml\n[source,yaml]\n----\n!Data1 {\n  name: Tom,\n  age: 25,\n  address: \"21 High street, Liverpool\"\n}\n----\n\n.cfg2.yaml\n[source,yaml]\n----\n!run.chronicle.wire.demo.Example7$Data2 {\n  name: Helen,\n  age: 19,\n  address: \"15 Royal Way, Liverpool\"\n}\n----\n\nCreate instances of Data1 and Data2 by reading the above configuration files and print the created objects:\n\n[source,java,opts=novalidate]\n----\nData1 o1 = WireType.TEXT.fromFile(\"cfg1.yaml\");\nSystem.out.println(\"o1 = \" + o1);\n----\n\nprints:\n\n[source,text]\n----\no1 = !Data1 {\nname: Tom,\nage: 25,\naddress: \"21 High street, Liverpool\"\n}\n----\n\nand\n\n[source,java,opts=novalidate]\n----\nData2 o2 = WireType.TEXT.fromFile(\"cfg2.yaml\");\nSystem.out.println(\"o2 = \" + o2);\n----\n\nprints:\n\n[source,text]\n----\no2 = !run.chronicle.wire.demo.Example7$Data2 {\nname: Helen,\nage: 19,\naddress: \"15 Royal Way, Liverpool\"\n}\n----\n\nYou will see the complete package name for `o2` object.\n\n=== link:https://github.com/OpenHFT/Chronicle-Wire/blob/ea/demo/src/main/java/run/chronicle/wire/demo/Data.java[The code for the class Data]\n\n[source,java,opts=novalidate]\n----\nclass Data implements Marshallable {\n    private String message;\n    private long number;\n    private TimeUnit timeUnit;\n    private double price;\n\n    public Data() {\n    }\n\n    public Data(String message, long number, TimeUnit timeUnit, double price) {\n        this.message = message;\n        this.number = number;\n        this.timeUnit = timeUnit;\n        this.price = price;\n    }\n\n    public void setMessage(String message) {\n        this.message = message;\n    }\n\n    public void setNumber(long number) {\n        this.number = number;\n    }\n\n    public void setPrice(double price){\n        this.price =price;\n    }\n\n    public void setTimeUnit(TimeUnit timeUnit){\n        this.timeUnit = timeUnit;\n    }\n\n    public String getMessage() {\n        return message;\n    }\n\n    public long getNumber() {\n        return number;\n    }\n\n    public TimeUnit getTimeUnit() {\n        return timeUnit;\n    }\n\n    public double getPrice() {\n        return price;\n    }\n\n    @Override\n    public void readMarshallable(WireIn wire) throws IllegalStateException {\n        wire.read(\"message\").text(this, Data::setMessage)\n                .read(\"number\").int64(this, Data::setNumber)\n                .read(\"timeUnit\").asEnum(TimeUnit.class, this, Data::setTimeUnit)\n                .read(\"price\").float64(this,Data::setPrice);\n    }\n\n    @Override\n    public void writeMarshallable(WireOut wire) {\n        wire.write(\"message\").text(message)\n                .write(\"number\").int64(number)\n                .write(\"timeUnit\").asEnum(timeUnit)\n                .write(\"price\").float64(price);\n    }\n\n    @Override\n    public String toString() {\n        return \"Data{\" +\n                \"message='\" + message + '\\'' +\n                \", number=\" + number +\n                \", timeUnit=\" + timeUnit +\n                \", price=\" + price +\n                '}';\n    }\n}\n----\n\n== Wire type implementation details\n\n=== JSONWire\n\n==== Handling of special floating point values such as Double.NaN\n\nJSONWire will serialize and deserialize special floating point values such as `Double.NaN` to and from valid JSON string literals in accordance with the following table:\n\n[cols=\"2*\",options=\"header\"]\n|=================================================\n| Java primitive value     | String representation\n| Double.NaN               | \"NaN\"\n| Double.POSITIVE_INFINITY | \"Infinity\"\n| Double.NEGATIVE_INFINITY | \"-Infinity\"\n| Float.NaN                | \"NaN\"\n| Float.POSITIVE_INFINITY  | \"Infinity\"\n| Float.NEGATIVE_INFINITY  | \"-Infinity\"\n|=================================================\n\n=== YAML Anchors and Aliases\n\nChronicle Wire supports YAML anchors (`\u0026`) and aliases (`*`) which allow you to reuse values within a YAML document.\nThis feature is particularly useful for configuration files where you want to share common values across multiple sections.\n\n=== Basic Usage\n\nAnchors are defined using `\u0026anchorName` and referenced using `*anchorName`.\nThe following example demonstrates sharing a hostname across multiple service configurations.\n\n[source,yaml]\n----\ndatabase:\n  host: \u0026dbHost \"production.example.com\"\n  port: 5432\n  username: admin\ncache:\n  host: *dbHost        # Reuses the same host\n  port: 6379\n  timeout: 30\nbackup:\n  host: *dbHost        # Reuses the same host\n  port: 5432           # The port is not anchored, so it's a separate value\n  schedule: \"0 2 * * *\"\n----\n\n=== Code Example\n\n==== Data Classes\n\nThese are the simple DTO (Data Transfer Object) classes used for deserializing the YAML.\n\n[source,java,opts=novalidate]\n----\nstatic class DatabaseConfig extends SelfDescribingMarshallable {\n    String host;\n    int port;\n    String username;\n}\n\nstatic class CacheConfig extends SelfDescribingMarshallable {\n    String host;\n    int port;\n    int timeout;\n}\n\nstatic class BackupConfig extends SelfDescribingMarshallable {\n    String host;\n    int port;\n    String schedule;\n}\n\nstatic class SystemConfig extends SelfDescribingMarshallable {\n    DatabaseConfig database;\n    CacheConfig cache;\n    BackupConfig backup;\n}\n----\n\n==== Basic Field Anchors\n\nThis test shows how a string value for `host` is defined once with an anchor (`\u0026dbHost`) and reused twice with an alias (`*dbHost`).\nChronicle Wire ensures that the reused string is the same instance in memory.\n\n[source,java,opts=novalidate]\n----\nString yaml = \"\" +\n        \"database: {\\n\" +\n        \"  host: \u0026dbHost \\\"production.example.com\\\",\\n\" +\n        \"  port: 5432,\\n\" +\n        \"  username: admin\\n\" +\n        \"}\\n\" +\n        \"cache: {\\n\" +\n        \"  host: *dbHost,\\n\" +\n        \"  port: 6379,\\n\" +\n        \"  timeout: 30\\n\" +\n        \"}\\n\" +\n        \"backup: {\\n\" +\n        \"  host: *dbHost,\\n\" +\n        \"  port: 5432,\\n\" +\n        \"  schedule: \\\"0 2 * * *\\\"\\n\" +\n        \"}\\n\";\n\n// Deserialize directly to the SystemConfig DTO\nSystemConfig systemConfig = WireType.YAML.fromString(SystemConfig.class, yaml);\n\nassertEquals(\"production.example.com\", systemConfig.database.host);\nassertSame(systemConfig.cache.host, systemConfig.database.host);\nassertSame(systemConfig.backup.host, systemConfig.database.host);\n----\n\n=== Object Anchors\n\nYou can also anchor and reuse entire objects, not just scalar values.\nThis is powerful for defining default configurations that can be applied to multiple components.\n\n==== Server Config Classes\n\n[source,java,opts=novalidate]\n----\nstatic class ServerConfig extends SelfDescribingMarshallable {\n    int timeout;\n    int retries;\n    String logLevel;\n}\n\nstatic class MonitorConfig extends SelfDescribingMarshallable {\n    ServerConfig server;\n    int interval;\n}\n\nstatic class ServerSystemConfig extends SelfDescribingMarshallable {\n    ServerConfig defaults;\n    ServerConfig primary;\n    ServerConfig secondary;\n    MonitorConfig monitoring;\n}\n----\n\n==== Object Anchor Example\n\nIn this example, a complete `ServerConfig` object is defined and anchored as `\u0026defaultServer`.\nThis exact same object instance is then referenced for the `primary`, `secondary`, and `monitoring` server configurations.\n\n[source,java,opts=novalidate]\n----\nString yaml = \"\" +\n        \"defaults: \u0026defaultServer !net.openhft.chronicle.wire.YamlAnchorExamplesTest$ServerConfig {\\n\" +\n        \"  timeout: 30,\\n\" +\n        \"  retries: 3,\\n\" +\n        \"  logLevel: INFO\\n\" +\n        \"}\\n\" +\n        \"primary: *defaultServer\\n\" +\n        \"secondary: *defaultServer\\n\" +\n        \"monitoring: {\\n\" +\n        \"  server: *defaultServer,\\n\" +\n        \"  interval: 60\\n\" +\n        \"}\\n\";\n\n// Deserialize directly to the top-level object\nServerSystemConfig config = WireType.YAML.fromString(ServerSystemConfig.class, yaml);\n\n// Verify object references work - they should be the same object instance\nassertSame(\"primary should be same object as defaults\", config.defaults, config.primary);\nassertSame(\"secondary should be same object as defaults\", config.defaults, config.secondary);\nassertSame(\"monitoring.server should be same object as defaults\", config.defaults, config.monitoring.server);\n\n// Verify the values\nassertEquals(30, config.defaults.timeout);\nassertEquals(3, config.defaults.retries);\nassertEquals(\"INFO\", config.defaults.logLevel);\nassertEquals(60, config.monitoring.interval);\n----\n\n== LongConverter\n\nProvides an abstraction for converting between long values and their string representations, potentially based on a custom character or symbol set.\n\nThe conversion allows encoding long values into compact, human-readable strings and vice versa, useful in contexts where storage efficiency is a concern.\n\nSome example `LongConverters` are `NanoTimestampLongConverter` which stores a nanosecond timestamp as a long and renders it as a human-readable timestamp, or `Base64LongConverter` which can store a string of up to 11 characters in a long.\n\n`LongConverter` can also convert byte, short, char, and int fields.\n\nFor example:\n\n[source,java,opts=novalidate]\n----\n    long ts = NanoTimestampLongConverter.INSTANCE.parse(\"2023-02-15T05:31:49.856123456\");\n    System.out.println(ts); // 1676439109856123456\n    System.out.println(NanoTimestampLongConverter.INSTANCE.asString(ts)); // \"2023-02-15T05:31:49.856123456\"\n----\n\nand\n\n[source,java,opts=novalidate]\n----\n    long code = Base64LongConverter.INSTANCE.parse(\"UXX0UXZ0\");\n    System.out.println(code); // 94034908776117\n    System.out.println(Base64LongConverter.INSTANCE.asString(code));\n----\n\nIf you are writing your own converters you may wish to use the more concise style of custom annotation.\n\n----\n/**\n* Annotate fields or parameters to signify the long value represents a Nanosecond resolution timestamp from epoch.\n*/\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.FIELD, ElementType.PARAMETER})\n@LongConversion(NanoTime.class)                                            //// \u003c- required\npublic @interface NanoTime {\n    LongConverter INSTANCE = new NanoTimestampLongConverter();             //// \u003c- required\n}\n\n/**\n* Annotate fields or parameters to signify the long value represent a String of 0 to 10 characters in Base85\n*/\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.FIELD, ElementType.PARAMETER})\n@LongConversion(Base85.class)\npublic @interface Base85 {\n    LongConverter INSTANCE = Base85LongConverter.INSTANCE;\n}\n\n----\n\nNOTE:: The annotation must have a field called `INSTANCE` to act as the converter\n\n----\npublic class Person extends SelfDescribingMarshallable {\n    private String name;\n    @NanoTime\n    private long timestampNS;\n    @Base85\n    private long userName;\n----\n\n== A note on `Wires.reset()`\n\nChronicle Wire allows (and encourages) objects to be re-used in order to reduce allocation rates.\n\nWhen a marshallable object is re-used or initialised by the framework, it is first reset by way of `Marshallable.reset()`\nwhich is recommended over calling `Wires.reset()`.\nIn the case of most DTOs with simple scalar values, this will not cause any issues.\nHowever, more complicated objects with object instance fields may experience undesired behaviour.\n\nIn order to `reset` a marshallable object, the process is as follows:\n\n. create a new instance of the object to be reset (this is done just once per object type, then cached)\n. reset all fields, so that\n.. when the field value implements `Resettable` interface, and the default value of the field is not `null`, and the current field value is of exactly the same class as the default value, `value.reset()` will be called.\nThis behavior is introduced in Chronicle Wire `2.25`.\n.. when the field type is `Collection` or `Map`, and the default value is empty collection, it will be cleared.\n.. there is specific built-in copy-by-value handling for some types such as `Bytes`\n.. all other fields will be copied by reference from the new instance to the existing instance\n. the existing instance is now considered 'reset' back to default values\n\nThe object created in step `1` is cached for performance reasons, meaning that both the new and existing instance of the marshallable object could have a reference to the same object.\n\nWhile this will not be a problem for primitive or immutable values (for example, `int`, `Long`, `String`), a mutable field such as `ByteBuffer` will cause problems.\nConsider the following case:\n\n[source,java,opts=novalidate]\n----\npublic class BufferContainer {\n    private final ByteBuffer b = ByteBuffer.allocate(16);\n}\n\n@Test\npublic void shouldDemonstrateMutableFieldIssue2() {\n    // create 2 instances of a marshallable POJO\n    final BufferContainer c1 = new BufferContainer();\n    final BufferContainer c2 = new BufferContainer();\n    // reset both instances - this will set each container's\n    // b field to a 'default' value\n    Wires.reset(c1);\n    Wires.reset(c2);\n    // write to the buffer in c1\n    c1.b.putInt(42);\n    // inspect the buffer in both c1 and c2\n    System.out.println(c1.b.position());\n    System.out.println(c2.b.position());\n    System.out.println(c1.b == c2.b);\n}\n----\n\nThe output of the test above is:\n\n----\n4\n4\ntrue\n----\n\nshowing that the field *b* of each container object is now referencing the same `ByteBuffer` instance.\n\nAn exception to this is when the field value implements `Resettable` interface, when the default value of the field is not null, and the current field value is of exactly the same class as the default value.\nIn this case, `value.reset()` will be called instead of overwriting it with default value by reference.\n\nIn order to work around this, if necessary, the marshallable class can override `Marshallable.reset`:\n\n[source,java,opts=novalidate]\n----\npublic class BufferContainer implements Marshallable {\n    private ByteBuffer b = ByteBuffer.allocate(16);\n\n    @Override\n    public void reset() {\n        // or acquire from a pool if allocation should\n        // be kept to a minimum\n        b = ByteBuffer.allocate(16);\n    }\n}\n----\n\nIf the field type implements `Resettable` (including `Marshallable` classes), and the field has non-`null` default value, the existing value will be reset without creating any extra garbage:\n\n[source,java,opts=novalidate]\n----\npublic class ComplexDto implements SelfDescribingMarshallable {\n    private ContainedDto v = new ContainedDto(); // reset() will be propagated to this value\n}\n\npublic class ContainedDto implements SelfDescribingMarshallable {\n    // more fields which would be reset by default reset() implementation\n}\n----\n\n== Binding to a field value\n\nWhile serialized data can be updated by replacing a whole record, this might not be the most efficient option, nor thread-safe.\n\nChronicle Wire offers the ability to bind a reference to a fixed value of a field, and perform atomic operations on that field; for example, volatile read/write, and compare-and-swap.\n\n[source,java,opts=novalidate]\n----\n   // field to cache the location and object used to reference a field.\n   private LongValue counter = null;\n\n   // find the field and bind an approritae wrapper for the wire format.\n   wire.read(COUNTER).int64(counter, x -\u003e counter = x);\n\n   // thread safe across processes on the same machine.\n   long id = counter.getAndAdd(1);\n----\n\nOther types are supported; for example, 32-bit integer values, and an array of 64-bit integer values.\n\n== Pass-by-name or Dynamic Enums\n\nChronicle Wire supports passing objects reference by the `name()` of the object referenced.\nThis is supported trivially with `enum` which define a `name()` for you. e.g.\n\n.Passing a reference to an enum using it's name\n[source,java,opts=novalidate]\n----\nenum ServerId {\n    LN_A\n}\n\ninterface Output {\n    void serverId(ServerId serverId);\n}\n\n// later\nOutput out; // is a MethodWriter\n\nout.serverId(ServerId.LN_A);\n----\n\n.Message on the Wire\n[source,yaml]\nserverId: LN_A\n\nHowever, we might wish to alter metadata associated with the enum\n\n[source,java,opts=novalidate]\n----\nenum ServerId implements DynamicEnum {\n    LN_A(101);\n\n    public int priority;\n}\n----\n\n=== Not passing by name\n\nSometimes you need to pass the actually data, esp the first time.\nThis can be achieved by using the `@AsMarshallable` annotation which will always pass the object as a typedMarshallable.\n\n[source,java,opts=novalidate]\n----\npublic class RefData extends AbstractEventCfg\u003cRefData\u003e {\n    @AsMarshallable\n    private final DynamicEnum data;\n\n    public RefData(DynamicEnum data) {\n        this.data = data;\n    }\n\n    public DynamicEnum data() {\n        return data;\n    }\n}\n----\n\nYou can choose to update the existing `enum` with this information.\n\n[source,java,opts=novalidate]\n----\npublic void refData(RefData refData) {\n    DynamicEnum.updateEnum(refData.data);\n}\n----\n\n[source,yaml]\n----\nrefData: {\n    eventId: GUI,\n    eventTime: 2020-09-09T09:09:09.999,\n    data: !ServerId {\n        name: LN_A,\n        priority: 128\n    }\n}\n----\n\nNOTE: You can add an enum which didn't exist.\n\n[source,yaml]\n----\nrefData: {\n    eventId: GUI,\n    eventTime: 2020-09-09T09:09:09.999,\n    data: !ServerId {\n        name: HK_A,\n        priority: 200\n    }\n}\n----\n\nNOTE: You can't use an enum before it is defined, this is assumed to be in input error.\n\n=== Pass by reference\n\nYou may wish to pass by reference a data type which is not an enum.\nThis can be done by adding `DynamicEnum` to a regular class and adding a `name` field.\n\n[source,java,opts=novalidate]\n----\nclass MyData implements DynamicEnum {\n    public static final MyData ONE = new MyData(\"One\"); // used as a predefined object\n    public static final MyData TWO = new MyData(\"Two\"); // used as a predefined object\n    private String name; // set via reflection.\n\n    @Override public String name() { return name; }\n}\n----\n\nNOTE: This is particularly useful if you have a class which must extend another parent.\n\n[source,yaml]\n----\n---\nmyData: One # uses predefined value\n...\n---\nmyData: Two # uses predefined value\n...\n---\nrefData: {\n    eventId: GUI,\n    eventTime: 2020-09-09T09:09:09.999,\n    data:  !MyData {\n        name: Three\n   }\n}\n...\n---\nmyData: Three # use the one just defined\n...\n---\nmyData: Four # will error as doesn't exist.\n...\n----\n\nThe consumer doesn't need to do anything special to use the new enum, however the producer need to create it in code as follows.\n\n[source,java,opts=novalidate]\n----\nServerId serverId = EnumCache.of(ServerId.class).nameFor(\"HK_A\");\nserverId.priority(200);\nout.refData(new RefData(serverId));\n\nMyData myData = EnumCache.of(MyData.class).nameFor(\"Three\");\nout.refData(new RefData(myData));\n----\n\nNOTE: The unique key for these objects is their type and name.\nTwo objects of different types can have the same name.\n\nIMPORTANT: These objects passed by reference are never cleaned up.\nOnly use them when there is likely to be a limited number of them over the life of the application.\n\n== Using @MethodId\n\nYou can assign a method id to a method using the annotation `@MethodId(long int: id)`.\nThe provided id should be unique across all classes using the same MethodReader/Writer, therefore it is safe practice to use unique method id in your entire system.A method name can be determined from its method id and this results in saving memory when calling the method.The following example shows the difference between memory usage when using method id and when not using it.In this example the method `saysomethingnice()` has been annotated with `MethodId(7)` and it has been called from `shouldDetermineMethodNamesFromMethodIds()`.\n\n[source,java,opts=novalidate]\n----\n\n interface Speaker {\n     @MethodId(7)\n     void saysomethingnice(final String message);\n }\n\n void shouldDetermineMethodNamesFromMethodIds() {\n     Bytes\u003c?\u003e bytes = Bytes.allocateElasticOnHeap();\n\n     final BinaryWire wire = new BinaryWire(bytes);\n     final Speaker speaker =\n             wire.methodWriterBuilder(Speaker.class).get();\n     speaker.saysomethingnice(\"hello\");\n----\n\n.Using a @MethodId\n----\n08 00 00 00                                     # msg-length\nba 07                                           # say\ne5 68 65 6c 6c 6f                               # hello\n----\n\n.Without a @MethodId\n----\n0b 00 00 00                                     # msg-length\nb9 03 73 61 79                                  # say\ne5 68 65 6c 6c 6f                               # hello\n----\n\n== Bytes options\n\nChronicle Wire is built on top of the `Bytes` library, however `Bytes`, in turn, can wrap:\n\n* `ByteBuffer` - heap and direct\n* `byte[]` - using `ByteBuffer`\n* `byte[]` or primitive array without ByteBuffer\n* raw memory addresses.\n* portion of a regular on heap object\n\n== Handling instance classes of an unknown type\n\nThis feature allows Chronicle Wire to de-serialize, manipulate, and serialize an instance class of an unknown type.\n\nIf the type is unknown at runtime, a proxy is created; assuming that the required type is an interface.\n\nWhen the tuple is serialized, it will be give the same type as when it was deserialized, even if that class is not available.\n\nMethods following our `getter`/`setter` convention will be treated as `getters` and `setters`.\n\nThis feature is needed for a service that stores and passes on data, for classes it might not have in its class path.\n\nNOTE: This is not garbage collection free, but if the volume is low, this may be easier to work with.\n\nNOTE: This only works when the expected type is not a class.\n\n=== LongConversionExample\n\n[source,java,opts=novalidate]\n----\n@Test\npublic void unknownType() throws NoSuchFieldException {\n    Marshallable marshallable = Wires.tupleFor(Marshallable.class, \"UnknownType\");\n    marshallable.setField(\"one\", 1);\n    marshallable.setField(\"two\", 2.2);\n    marshallable.setField(\"three\", \"three\");\n    String toString = marshallable.toString();\n    assertEquals(\"!UnknownType {\\n\" +\n            \"  one: !int 1,\\n\" +\n            \"  two: 2.2,\\n\" +\n            \"  three: three\\n\" +\n            \"}\\n\", toString);\n    Object o = Marshallable.fromString(toString);\n    assertEquals(toString, o.toString());\n}\n\n@Test\npublic void unknownType2() {\n    String text = \"!FourValues {\\n\" +\n            \"  string: Hello,\\n\" +\n            \"  num: 123,\\n\" +\n            \"  big: 1e6,\\n\" +\n            \"  also: extra\\n\" +\n            \"}\\n\";\n    ThreeValues tv = Marshallable.fromString(ThreeValues.class, text);\n    assertEquals(text, tv.toString());\n    assertEquals(\"Hello\", tv.string());\n    tv.string(\"Hello World\");\n    assertEquals(\"Hello World\", tv.string());\n\n    assertEquals(123, tv.num());\n    tv.num(1234);\n    assertEquals(1234, tv.num());\n\n    assertEquals(1e6, tv.big(), 0.0);\n    tv.big(0.128);\n    assertEquals(0.128, tv.big(), 0.0);\n\n    assertEquals(\"!FourValues {\\n\" +\n            \"  string: Hello World,\\n\" +\n            \"  num: !int 1234,\\n\" +\n            \"  big: 0.128,\\n\" +\n            \"  also: extra\\n\" +\n            \"}\\n\", tv.toString());\n\n}\n\ninterface ThreeValues {\n    ThreeValues string(String s);\n    String string();\n\n    ThreeValues num(int n);\n    int num();\n\n    ThreeValues big(double d);\n    double big();\n}\n----\n\n== Handling unexpected fields\n\nBy default, Chronicle Wire skips fields which names don't match any field of the DTO class.\nIt's possible to capture such fields by overriding method or `ReadMarshallable`:\n\n[source,java,opts=novalidate]\n----\n    default void unexpectedField(Object event, ValueIn valueIn) {\n        valueIn.skipValue();\n    }\n----\n\nOne of best practices is saving unexpected fields in order to process them after the deserialization:\n\n[source,java,opts=novalidate]\n----\n        transient Map\u003cString, Object\u003e others = new LinkedHashMap\u003c\u003e();\n\n        @Override\n        public void unexpectedField(Object event, ValueIn valueIn) {\n            others.put(event.toString(), valueIn.object());\n        }\n----\n\nIt's also possible to use fail-fast approach and throw an exception:\n\n[source,java,opts=novalidate]\n----\n        @Override\n        public void unexpectedField(Object event, ValueIn valueIn) {\n            throw new IllegalStateException(\"Unexpected field: name=\" + event + \", value=\" + valueIn);\n        }\n----\n\nExceptions that are thrown from this method are never swallowed, they are wrapped into runtime `UnexpectedFieldHandlingException` and thrown back to a high-level API call.\n\n== LongConversionExample with `MethodReaders`\n\n[source,java,opts=novalidate]\n----\n@Test\npublic void testUnknownClass() {\n    Wire wire2 = new TextWire(Bytes.elasticHeapByteBuffer(256));\n    MRTListener writer2 = wire2.methodWriter(MRTListener.class);\n\n    String text = \"top: !UnknownClass {\\n\" +\n            \"  one: 1,\\n\" +\n            \"  two: 2.2,\\n\" +\n            \"  three: words\\n\" +\n            \"}\\n\" +\n            \"---\\n\" +\n            \"top: {\\n\" +\n            \"  one: 11,\\n\" +\n            \"  two: 22.2,\\n\" +\n            \"  three: many words\\n\" +\n            \"}\\n\" +\n            \"---\\n\";\n    Wire wire = TextWire.from(text);\n    MethodReader reader = wire.methodReader(writer2);\n    assertTrue(reader.readOne());\n    assertTrue(reader.readOne());\n    assertFalse(reader.readOne());\n    assertEquals(text, wire2.toString());\n}\n----\n\n=== Filtering with MethodReaders\n\nTo support filtering, you need to make sure the first of multiple arguments can be used to filter the method call.\nIf you have only one argument, you may need to add an additional argument to support efficient filtering.\n\nThis feature calls an implementation of `MethodFilterOnFirstArg` to see if the rest of the method call should be parsed.\nFor example, today you have:\n\n[source,java,opts=novalidate]\n----\ninterface MyInterface {\n    void method(ExpensiveDto dto);\n}\n----\n\nThis can be migrated to:\n\n[source,java,opts=novalidate]\n----\ninterface MyInterface extends MethodFilterOnFirstArg\u003cString\u003e {\n    @Deprecated\n    void method(ExpensiveDto dto);\n    void method2(String filter, ExpensiveDto dto);\n}\n----\n\nwhere the implementation can look like this:\n\n[source,java,opts=novalidate]\n----\nclass MyInterfaceImpl extends MyInterface {\n    public void method(ExpensiveDto dto) {\n       // something\n    }\n\n    public void method2(String filter, ExpensiveDto dto) {\n        method(dto);\n    }\n\n    public boolean ignoreMethodBasedOnFirstArg(String methodName, String filter) {\n        return someConditionOn(methodName, filter);\n    }\n}\n----\n\nFor an example, see `net.openhft.chronicle.wire.MethodFilterOnFirstArgTest`.\n\n=== Intercepting `MethodReader` calls\n\nYou may wish to intercept handling a call in the method reader in order to execute additional logic, to record a call somewhere for monitoring purposes, or to even skip the original method invocation.\n\n==== Intercepting by passing control over the original method call\n\n`MethodReader` provides a flexible feature for supporting all the above use cases -- the option to specify `MethodReaderInterceptorReturns`.\nIf set, it will be triggered *instead* of the original call.\nIt's possible to either skip the original method or to call it via passed `Invocation` instance:\n\n[source,java,opts=novalidate]\n----\nclass MyInterceptor implements MethodReaderInterceptorReturns {\n    @Override\n    Object intercept(Method m, Object o, Object[] args, Invocation invocation) throws InvocationTargetException {\n        // Execute any logic you want before the call\n        if (some_condition)\n            invocation.invoke(m, o, args); // Invoke the original method if needed\n        // Execute any logic you want after the call\n    }\n}\n----\n\n==== Intercepting by modifying `MethodReader` generated source code\n\n`GeneratingMethodReaderInterceptorReturns` allows to change the logic of `MethodReader` without an overhead provided by reflexive calls.\n\nCode returned by `codeBeforeCall` and `codeAfterCall` will be added before and after actual method call in the generated source code of the method reader.\nIt's possible to use original call arguments and object instance in the added code.\n\nSimple example that enforces skipping the original call in case the second agrument is `null`:\n\n[source,java,opts=novalidate]\n----\nclass SkippingInterceptor implements GeneratingMethodReaderInterceptorReturns {\n    @Override\n    public String generatorId() {\n        return \"skipping\";\n    }\n\n    @Override\n    public String codeBeforeCall(Method m, String objectName, String[] argumentNames) {\n        return \"if (\" + argumentNames[1] + \" != null) {\";\n    }\n\n    @Override\n    public String codeAfterCall(Method m, String objectName, String[] argumentNames) {\n        return \"}\";\n    }\n}\n----\n\nIf the code provided by generating interceptor differs from the code provided by another generating interceptor, their `generatorId` should be different as well.\nIt's needed to ensure re-compilation in case a new interceptor is passed.\n\nSee `MethodReaderInterceptorReturnsTest` for more examples.\n\n=== Spring Boot and dynamic compilation in Chronicle Wire\n\nChronicle Wire's `MethodReader` and `MethodWriter` dynamically compile Java code to get around some limitations in Java's underlying proxy mechanism and to do this the Java platform's standard compilation mechanism is used.\nThe platform compiler uses the classpath variable to look for classes in directories and JAR files, and is not able to make use of classloaders to find classes.\nSpring Boot uses a custom deployment mechanism - all classes and JARs are deployed in a fat JAR and Spring's classloader can extract classes from this.\nIn order for the compiler to be able to see classes from the fat JAR, the classes should be extracted onto the disk somewhere.\nThis is easy if the classes are contained in a JAR (i.e. a JAR inside the fat JAR) - Spring can be made to extract the JAR to a temp directory, such as by configuring Maven Spring Boot plugin:\n\n[source,xml]\n----\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-maven-plugin\u003c/artifactId\u003e\n    \u003cconfiguration\u003e\n        \u003crequiresUnpack\u003e\n            \u003cdependency\u003e\n                \u003cgroupId\u003enet.openhft\u003c/groupId\u003e\n                \u003cartifactId\u003echronicle-bytes\u003c/artifactId\u003e\n            \u003c/dependency\u003e\n            \u003cdependency\u003e\n                \u003cgroupId\u003enet.openhft\u003c/groupId\u003e\n                \u003cartifactId\u003echronicle-core\u003c/artifactId\u003e\n            \u003c/dependency\u003e\n            \u003cdependency\u003e\n                \u003cgroupId\u003enet.openhft\u003c/groupId\u003e\n                \u003cartifactId\u003echronicle-wire\u003c/artifactId\u003e\n            \u003c/dependency\u003e\n        \u003c/requiresUnpack\u003e\n    \u003c/configuration\u003e\n\u003c/plugin\u003e\n----\n\nThis will allow the latest Chronicle-Wire to use classes in those JAR files.\n\nDynamic compilation may be also configured via Gradle Spring Boot plugin:\n\n[source,groovy]\n----\nbootJar {\n    requiresUnpack '**/chronicle-*.jar'\n}\n----\n\nNOTE: For more information see link:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.build.extract-specific-libraries-when-an-executable-jar-runs[Extract Specific Libraries When an Executable JAR Runs] and link:https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-configuring-unpacking[Spring Boot Gradle Plugin Reference Guide].\n\n== Using MethodWriter and MethodReader\n\nChronicle Wire's `MethodWriter` is used for writing data, and `MethodReader` is used for then reading this data.\nHowever, there are many use cases for them.\nOne of many benefits to these are their ease of use.\n\nIn particular, link:https://vanilla-java.github.io/2016/03/23/Microservices-in-the-Chronicle-world-Part-1.html[this article] captures the simplicity of using `MethodWriter` and `MethodReader`.\n\nIn another example, link:https://dzone.com/articles/java-how-to-leverage-method-chaining-to-add-smart[here], we can see how written data could be sent as a streaming event over an Event-Driven architecture, and then a `MethodReader` could be used to read these streaming events.\n\nThese are also not limited to being used only within Chronicle Wire.\nWith Chronicle Queue for instance, another example would be to have a `MethodWriter` that serialises and writes a method call to the out queue, and a `MethodReader` that reads in the in queue for any methods implemented.\nFor more detail about this example, see link:https://github.com/OpenHFT/Chronicle-Queue-Demo/blob/c1e128545e8f219daa186836ca58a07047436084/md-pipeline/src/main/java/org/trading/Runner.java[here].\n\n== Uses of Chronicle Wire\n\nChronicle Wire can be used for:\n\n* file headers\n* TCP connection headers; where the optimal wire format that is actually used can be negotiated\n* message/excerpt contents\n* Chronicle Queue version 4.x and later\n* the API for marshalling generated data types\n\n== Similar projects\n\n=== Simple Binary Encoding (SBE)\n\nSimple Binary Encoding (SBE) is designed to be a more efficient replacement for FIX.\nIt is not limited to FIX protocols, and can be easily extended by updating an XML schema.\nIt is simple, binary, and it supports C{pp} and Java.\n\nXML, when it first started, did not use XML for its own schema files, and it is not insignificant that SBE does not use SBE for its schema either.\nThis is because it is not trying to be human-readable.\nIt has XML which, though standard, is not designed to be human-readable either.\nChronicle believes that it is a limitation that it does not naturally lend itself to a human-readable form.\n\nThe encoding that SBE uses is similar to binary; with field numbers and fixed-width types.\n\nSBE assumes the field types, which can be more compact than Chronicle Wire's most similar option; though not as compact as others.\n\nSBE has support for schema changes provided that the type of a field doesn't change.\n\n=== Message Pack (`msgpack`)\n\nMessage Pack is a packed binary wire format which also supports `JSON` for human readability and compatibility.\nIt has many similarities to the binary (and `JSON`) formats of this library.\nChronicle Wire is designed to be human-readable first, based on `YAML`, and has a range of options to make it more efficient.\nThe most extreme being fixed position binary.\n\nMessage Pack has support for embedded binary, whereas Chronicle Wire has support for comments and hints, to improve rendering for human consumption.\n\nThe documentation looks well-thought-out, and it is worth emulating.\n\n=== Comparison with Cap'n'Proto\n\n|===============\n| Feature                          | Wire Text              | Wire Binary         | Protobuf               | Cap'n Proto             | SBE                 | FlatBuffers\n| Schema evolution                 | yes                    | yes                 | yes                    | yes                     | caveats             | yes\n| Zero-copy                        | yes                    | yes                 | no                     | yes                     | yes                 | yes\n| Random-access reads              | yes                    | yes                 | no                     | yes                     | no                  | yes\n| Random-access writes             | yes                    | yes                 | no                     | ?                       | no                  | ?\n| Safe against malicious input     | yes                    | yes                 | yes                    | yes                     | yes                 | opt-in / upfront\n| Reflection / generic algorithms  | yes                    | yes                 | yes                    | yes                     | yes                 | yes\n| Initialization order             | any                    | any                 | any                    | any                     | preorder            | bottom-up\n| Unknown field retention          | yes                    | yes                 | yes                    | yes                     | no                  | no\n| Object-capability RPC system     | yes                    | yes                 | no                     | yes                     | no                  | no\n| Schema language                  | no                     | no                  | custom                 | custom                  | XML                 | custom\n| Usable as mutable state          | yes                    | yes                 | yes                    | no                      | no                  | no\n| Padding takes space on wire?     | optional               | optional            | no                     | optional                | yes                 | yes\n| Unset fields take space on wire? | optional               | optional            | no                     | yes                     | yes                 | no\n| Pointers take space on wire?     | no                     | no                  | no                     | yes                     | no                  | yes\n| Pass-by-name (Dynamic Enums)     | yes                    | no                  | no                     | no                      | no                  | no\n| C`                               | yes                    | planned             | yes                    | yes (C`11)*             | yes                 | yes\n| Java                             | Java 8                 | Java 8              | yes                    | yes*                    | yes                 | yes\n| C#                               | yes                    | yes                 | yes                    | yes*                    | yes                 | yes*\n| Go                               | no                     | no                  | yes                    | yes                     | no                  | yes*\n| Other languages                  | no                     | no                  | 6+                     | others*                 | no                  | no\n| Authors' preferred use case      | distributed computing | financial / trading | distributed computing | platforms / sandboxing | financial / trading | games\n|===============\n\nNOTE: The `Binary YAML` format can be automatically converted to `YAML` without any knowledge of the schema, because the messages are self-describing.\n\nNOTE: You can parse all the expected fields (if any) and then parse any remaining fields.\nAs `YAML` supports object field names (or keys), these could be strings or even objects as keys and values.\n\nBased on https://capnproto.org/news/2014-06-17-capnproto-flatbuffers-sbe.html\n\nNOTE: It is not clear what padding which does not take up space on the wire means.\n\n== Design notes\n\nSee https://capnproto.org/news/2014-06-17-capnproto-flatbuffers-sbe.html for a comparison to other encoders.\n\n=== Schema evolution\n\nWire optionally supports:\n\n* field name changes\n* field order changes\n* capturing or ignoring unexpected fields\n* setting of fields to the default, if not available\n* raw messages can be longer or shorter than expected\n\nThe more flexibility, the larger the overhead in terms of CPU and memory.\nChronicle Wire allows you to dynamically pick the optimal configuration, and convert between these options.\n\n=== Zero copy\n\nChronicle Wire supports zero-copy random access to fields, and direct-copy from in-memory to the network.\nIt also supports translation from one wire format to another.\nFor example, switching between fixed-length data and variable-length data.\n\n=== Random Access\n\nYou can access a random field in memory, For example, in a `2TB` file, page-in/pull-into CPU cache, only the data relating to your read or write.\n\n[options=\"header\"]\n|===============\n| format | access style\n| fixed-length binary | random access without parsing first\n| variable-length binary | random access with partial parsing allowing you to skip large portions\n| fixed-length text | random access with parsing\n| variable-length text | no random access\n|===============\n\nChronicle Wire references are relative to the start of the data contained, to allow loading in an arbitrary point in memory.\n\n=== Safe against malicious input\n\nChronicle Wire has built in tiers of bounds checks to prevent accidental read/writing that corrupts the data.\nIt is not complete enough for a security review.\n\n=== Reflection / generic algorithms\n\nChronicle Wire supports generic reading and writing of an arbitrary stream.\nThis can be used in combination with predetermined fields.\nFor example, you can read the fields you know about, and ask it to provide the fields that you do not.\nYou can also give generic field names like keys to a map as `YAML` does.\n\n=== Initialization order\n\nChronicle Wire can handle unknown information like lengths, by using padding.\nIt will go back and fill in any data that it was not aware of when it was writing the data.\nFor example, when it writes an object, it does not know how long it is going to be, so it adds padding at the start.\nOnce the object has been written, it goes back and overwrites the length.\nIt can also handle situations where the length was more than needed; this is known as packing.\n\n=== Unknown field retention\n\nChronicle Wire can read data that it did not expect, interspersed with data it did expect.\nRather than specify the expected field name, a `StringBuilder` is provided.\n\nNOTE: There are times when you want to skip/copy an entire field or message, without reading any more of it.\nThis is also supported.\n\n=== Object-maximumLimit RPC system\n\nChronicle Wire supports references based on name, number, or UUID.\nThis is useful when including a reference to an object that the reader should look up by other means.\n\nA common case is if you have a proxy to a remote object, and you want to pass or return this in an RPC call.\n\n=== Schema language\n\nChronicle Wire's schema is not externalised from the code.\nHowever, it is planned to use `YAML` in a format that it can parse.\n\n=== Usable as mutable state\n\nChronicle Wire supports storing an application's internal state.\nThis will not allow it to grow or shrink.\nYou can't free any of it without copying the pieces that you need, and discarding the original copy.\n\n=== Padding takes space on the wire\n\nThe Chronicle Wire format that is chosen determines if there is any padding on the wire.\nIf you copy the in-memory data directly, its format does not change.\n\nIf you want to drop padding, you can copy the message to a wire format without padding.\nYou can decide whether the original padding is to be preserved or not, if turned back into a format with padding.\n\nWe could look at supporting _Cap'n'Proto_'s zero-byte removal compression.\n\n=== Un-set fields take space on the wire\n\nChronicle Wire supports fields with, and without, optional fields, and automatic means of removing them.\nChronicle Wire does not support automatically adding them back in, because information has been lost.\n\n=== Pointers take space on the wire\n\nChronicle Wire does not have pointers, but it does have content-lengths which are a useful hint for random access and robustness; but these are optional.\n\n== Working with IntelliJ\n\nThese templates can be added to IntelliJ to create simple getters and setters.\n\n.Simple Getter\n[source,velocity]\n----\n$field.type ##\n${field.name}() {\n  return $field.name;\n}\n----\n\n.Simple Setter\n[source,velocity]\n----\n#set($paramName = $helper.getParamName($field, $project))\n$class.name ${field.name}($field.type $paramName) {\n  this.$field.name = $paramName;\n  return this;\n}\n----\n\nSee also \u003c\u003c_code_generation_for_marshallable,Marshallable code generation templates\u003e\u003e\n\n== Why use Marshallable objects\n\nMarshallable objects have been designed to allow you to\n\n* write a simple POJO\n* have the `toString()`, `hashCode()` and `equals(Object)` methods created for you.\n* serialization to a human-readable format (based on YAML), as well as efficient binary formats.\n* the string format for text and binary can be logged and reconstructed from the text or hexadecimal dump\n* copying and conversion of data from one type to another\n\n== Pojo LongConversionExample\n\nThe following is a simple example of a POJO with a nested data type in a List.\n\n.A Simple Pojo without needing to define toString/hashCode/equals\n[source,java,opts=novalidate]\n----\nimport net.openhft.chronicle.wire.SelfDescribingMarshallable;\n\nclass MyPojo extends SelfDescribingMarshallable {\n    String text;\n    int num;\n    double factor;\n\n    public MyPojo(String text, int num, double factor) {\n        this.text = text;\n        this.num = num;\n        this.factor = factor;\n    }\n}\n\nclass MyPojos extends SelfDescribingMarshallable {\n    String name;\n    List\u003cMyPojo\u003e myPojos = new ArrayList\u003c\u003e();\n\n    public MyPojos(String name) {\n        this.name = name;\n    }\n}\n----\n\nBy extending `SelfDescribingMarshallable` the class has an implementation for `readMarshallable(WireIn)`, `writeMarshallable(WireOut)` and from these\n`toString()`, `hashCode()` and `equals(Object)`.\nYou only need to define the method yourself for improved efficiency.\nThese default implementations can give you 2/3rds of the performance of hand coding but save time and potential errors writing them yourself.\n\n=== The toString()\n\nAn important feature of the `toString()` method is no information is lost.\nThe object can be reconstructed from the output of the `toString()` method.\nThis is useful for building sample data in unit tests for from a file.\nIt also means that you can take the dump of an object in a log file and reconstruct the original object.\n\n[source,java,opts=novalidate]\n----\nMyPojos mps = new MyPojos(\"test-list\");\nmps.myPojos.add(new MyPojo(\"text1\", 1, 1.1));\nmps.myPojos.add(new MyPojo(\"text2\", 2, 2.2));\n\nSystem.out.println(mps); // \u003c1\u003e\n----\n\n\u003c1\u003e Uses the default `toString()` provided.\n\nprints\n\n[source,yaml]\n----\n!MyPojos {\n  name: test-list,\n  myPojos: [\n    { text: text1, num: 1, factor: 1.1 },\n    { text: text2, num: 2, factor: 2.2 }\n  ]\n}\n----\n\nYou can take the same output and reconstruct the original object.\n\n[source,java,opts=novalidate]\n----\nMyPojos mps2 = Marshallable.fromString(mps.toString());\nassertEquals(mps, mps2); // \u003c1\u003e\n\nString text = \"!MyPojos {\\n\" +\n        \"  name: test-list,\\n\" +\n        \"  myPojos: [\\n\" +\n        \"    { text: text1, num: 1, factor: 1.1 },\\n\" +\n        \"    { text: text2, num: 2, factor: 2.2 }\\n\" +\n        \"  ]\\n\" +\n        \"}\\n\";\nMyPojos mps3 = Marshallable.fromString(text);\nassertEquals(mps, mps3); // \u003c1\u003e\n----\n\n\u003c1\u003e `SelfDescribingMarshallable` also provides a default `equals(Object)` and `hashCode()`\n\nFinally, you can take data from a file and build the object.\n\n[source,java,opts=novalidate]\n----\nMyPojos mps4 = Marshallable.fromFile(\"my-pojos.yaml\");\nassertEquals(mps, mps4);\n----\n\n== Self describing messages\n\nWhen writing and reading from text, Marshallable are always self describing, however when using Binary there is two choices:\n`SelfDescribingMarshallable` which is self describing in binary and `BytesInBinaryMarshallable` which uses raw values.\n\n`SelfDescribingMarshallable` is slightly slower, and larger when writing but supports schema changes such as\n\n* Adding fields.\n* Removing fields\n* Changing the order of fields\n* Change the type of fields\n* Dumbing as text without access to the class specification.\n\n`BytesInBinaryMarshallable` is faster and more compact, however you need to add your own support for schema changes.\nSee the Code Generating section below.\n\n=== Code Generation for Marshallable\n\nInstall the Code Generation plugin, and add a template in `File` -\u003e `Settings` -\u003e `Code Generation` as follows.\n\nUse the `Add Member Dialog` button and `Exclude transient fields`\n\nThis will add more efficient code for Marshallable format.\n\n[source]\n.SelfDescribingMarshallable\n----\n#set($javaPsiFacade = $JavaPsiFacade.getInstance($project))\n#set($global = $GlobalSearchScope.allScope($project))\n\n@Override public void writeMarshallable(net.openhft.chronicle.wire.WireOut out) {\n#if($class0.superName != \"SelfDescribingMarshallable\")\n   super.writeMarshallable(out);\n#end\n#foreach( $member in $members )\n    #set($memberType = $member.type.split(\"\u003c\").get(0))\n    #set($type = $javaPsiFacade.findClass($memberType, $global))\n    #if ($member.primitive)\n        out.write(\"$member.name\").write${StringUtil.capitalizeWithJavaBeanConvention($memberType)}($member.name);\n    #else\n        out.write(\"$member.name\").object(${memberType}.class, $member.name);\n    #end\n#end\n}\n\n@Override public void readMarshallable(net.openhft.chronicle.wire.WireIn in) {\n#if($class0.superName != \"SelfDescribingMarshallable\")\n   super.readMarshallable(in);\n#end\n#foreach( $member in $members )\n    #set($memberType = $member.type.split(\"\u003c\").get(0))\n    #set($type = $javaPsiFacade.findClass($memberType, $global))\n    #if ($member.primitive)\n        $member.name = in.read(\"$member.name\").read${StringUtil.capitalizeWithJavaBeanConvention($memberType)}();\n    #else\n        $member.name = in.read(\"$member.name\").object($member.name, ${memberType}.class);\n    #end\n#end\n}\n----\n\n[source]\n.BytesInBinaryMarshallable\n----\n#set($javaPsiFacade = $JavaPsiFacade.getInstance($project))\n#set($global = $GlobalSearchScope.allScope($project))\n\nprivate static final int MASHALLABLE_VERSION = 1;\n\n@Override public void writeMarshallable(net.openhft.chronicle.bytes.BytesOut\u003c?\u003e out) {\n#if($class0.superName != \"BytesInBinaryMarshallable\")\n   super.writeMarshallable(out);\n#end\n   out.writeStopBit(MASHALLABLE_VERSION);\n#foreach( $member in $members )\n   #set($memberType = $member.type.split(\"\u003c\").get(0))\n   #set($type = $javaPsiFacade.findClass($memberType, $global))\n   #if ($member.primitive)\n       out.write${StringUtil.capitalizeWithJavaBeanConvention($memberType)}($member.name);\n   #else\n       out.writeObject(${memberType}.class, $member.name);\n   #end\n#end\n}\n\n@Override public void readMarshallable(net.openhft.chronicle.bytes.BytesIn\u003c?\u003e in) {\n#if($class0.superName != \"BytesInBinaryMarshallable\")\n   super.readMarshallable(in);\n#end\n   int version = (int) in.readStopBit();\n   if (version == MASHALLABLE_VERSION) {\n#foreach( $member in $members )\n   #set($memberType = $member.type.split(\"\u003c\").get(0))\n   #set($type = $javaPsiFacade.findClass($memberType, $global))\n   #if ($member.primitive)\n       $member.name = in.read${StringUtil.capitalizeWithJavaBeanConvention($memberType)}();\n   #else\n       $member.name = (${memberType})in.readObject(${memberType}.class);\n   #end\n#end\n   } else {\n       throw new IllegalStateException(\"Unknown version \" + version);\n   }\n}\n----\n\n[source]\n.BytesMarshallable\n----\n#set($javaPsiFacade = $JavaPsiFacade.getInstance($project))\n#set($global = $GlobalSearchScope.allScope($project))\n\nprivate static final int MASHALLABLE_VERSION = 1;\n\n@Override public void writeMarshallable(net.openhft.chronicle.bytes.BytesOut\u003c?\u003e out) {\n#if($class0.hasSuper)\n   super.writeMarshallable(out); // \u003c1\u003e\n#end\n  out.writeStopBit(MASHALLABLE_VERSION);\n#foreach( $member in $members )\n   #set($memberType = $member.type.split(\"\u003c\").get(0))\n   #set($type = $javaPsiFacade.findClass($memberType, $global))\n   #if ($member.primitive)\n       out.write${StringUtil.capitalizeWithJavaBeanConvention($memberType)}($member.name);\n   #else\n       out.writeObject(${memberType}.class, $member.name);\n   #end\n#end\n}\n\n@Override public void readMarshallable(net.openhft.chronicle.bytes.BytesIn\u003c?\u003e in) {\n#if($class0.hasSuper)\n   super.readMarshallable(in);\n#end\n   int version = (int) in.readStopBit();\n   if (version == MASHALLABLE_VERSION) {\n#foreach( $member in $members )\n   #set($memberType = $member.type.split(\"\u003c\").get(0))\n   #set($type = $javaPsiFacade.findClass($memberType, $global))\n   #if ($member.primitive)\n       $member.name = in.read${StringUtil.capitalizeWithJavaBeanConvention($memberType)}();\n   #else\n       $member.name = (${memberType})in.readObject(${memberType}.class);\n   #end\n#end\n   } else {\n       throw new IllegalStateException(\"Unknown version \" + version);\n   }\n}\n----\n\u003c1\u003e You will have to remove this line if the class extends `AbstractBytesMarshallable`\n\n=== JLBH Benchmark Performance\n\nTo explore the efficiency of the examples above, this link:https://github.com/OpenHFT/Chronicle-Wire/blob/develop/src/test/java/net/openhft/chronicle/wire/TriviallyCopyableJLBH.java[TrivallyCopyableJLBH.java] test was created.\nAs can be seen on lines 18-26, we have the ability to switch between running the TriviallyCopyable House (\"House1\"), the BinaryWire House (\"House2\") or 'UNKNOWN'.Important to note is that trivially copyable objects were used in order to improve java serialisation speeds.For further understanding on trivially copyable objects, refer to link:https://dzone.com/articles/how-to-get-c-speed-in-java-serialisation[this article].\nThis shows that we can serialise and then de-serialise 100,000 messages in a second.The Trivially Copyable version is even faster, especially at the higher percentiles.\n\n.Benchmark Performance Between TriviallyCopyable and BinaryWire\nimage::images/jlbhBenchmark.png[buffer,600,400]\n* Microseconds to both serialise and deserialise a message\n\n=== Platform support\n\nChronicle Wire supports `Java 8`, `Java 11` and `C{pp}`.\nFuture versions may support `Java 14`, `python`.\n\n'''\n\nhttps://github.com/OpenHFT/Chronicle-Wire[Back to Chronicle Wire project]\n\n== Network Channels in Wire\n\nChronicle Wire supports creating channels over TCP.\nThat `ChronicleChannel` acts as `MarshallableIn` and `MarshallableOut`, as `Wire` does, except that it writes to a TCP connection and reads from the same connection.\n\n=== Simple ChronicleChannel - EchoHandler\n\nWhen you create a channel, you specify what type of connection you want.\nThe simplest is an EchoHandler that echos everything you send it.\n\n[source,java,opts=novalidate]\n----\n// start a server on an unused port\nString url = \"tcp://:0\";\n// create a context for new channels, all channels are closed when the context is closed\ntry (ChronicleContext context = ChronicleContext.newContext(url)) {\n    // open a new channel that acts as an EchoHandler\n    ChronicleChannel channel = context.newChannelSupplier(new EchoHandler()).get();\n    // create a proxy that turns each call to Says into an event on the channel\n    Says say = channel.methodWriter(Says.class);\n    // add an event\n    say.say(\"Hello World\");\n    // ad a second event\n    say.say(\"Bye now\");\n\n    // A buffer so the event name can be returned as well\n    StringBuilder event = new StringBuilder();\n    // read one message excepting the object after the event name to be a String\n    String text = channel.readOne(event, String.class);\n    // check it matches\n    assertEquals(\"say: Hello World\", event + \": \" + text);\n\n    // read the second message\n    String text2 = channel.readOne(event, String.class);\n    // check it matches\n    assertEquals(\"say: Bye now\", event + \": \" + text2);\n}\n\n----\n\n== Documentation\n\n* link:src/main/docs/index.adoc[Documentation Index]\n* link:src/main/docs/wire-architecture.adoc[Architectural Overview]\n* link:src/main/docs/wire-schema-evolution.adoc[Schema Evolution Deep Dive]\n* link:src/main/docs/wire-cookbook.adoc[Cookbook]\n* link:src/main/docs/wire-faq.adoc[FAQ]\n* link:src/main/docs/wire-glossary.adoc[Glossary]\n* link:docs/EventsByMethod.adoc[Events by Method]\n* link:docs/YAML2SpecificationCompliance.adoc[YAML 1.2 Compliance]\n* link:docs/systemProperties.adoc[System Properties Guide]\n\n== Community and Support\n\nIssues and pull requests are welcome on the link:https://github.com/OpenHFT/Chronicle-Wire[GitHub repository].\nFor commercial support and additional information visit https://chronicle.software/.\n\n== License\n\nChronicle Wire is released under the link:LICENSE[Apache 2.0 License].\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhft%2Fchronicle-wire","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenhft%2Fchronicle-wire","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhft%2Fchronicle-wire/lists"}