> For the complete documentation index, see [llms.txt](https://alex-robenko.gitbook.io/comms-protocols-cpp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alex-robenko.gitbook.io/comms-protocols-cpp/head-3/sync.md).

# SYNC Layer

This layer is responsible to find and validate the synchronisation prefix.

```cpp
namespace comms
{
// TField is type of the field used to read/write SYNC prefix
// TNext is the next layer this one wraps
template <typename TField, typename TNext>
class SyncPrefixLayer
{
public:
    // Type of the field object used to read/write SYNC prefix.
    using Field = TField;

    // Take type of the ReadIterator from the next layer
    using ReadIterator = typename TNext::ReadIterator;

    // Take type of the WriteIterator from the next layer
    using WriteIterator = typename TNext::WriteIterator;

    // Take type of the message interface from the next layer
    using Message = typename TNext::Message;

    // Take type of the message interface pointer from the next layer
    using MsgPtr = typename TNext::MsgPtr; 

    template <typename TMsgPtr>
    ErrorStatus read(TMsgPtr& msgPtr, ReadIterator& iter, std::size_t len)
    {
        Field field;
        auto es = field.read(iter, len);
        if (es != ErrorStatus::Success) {
            return es;
        }
        if (field.value() != Field().value()) {
            // doesn't match expected
            return ErrorStatus::ProtocolError;
        }
        return m_next.read(msgPtr, iter, len - field.length());
    } 

    ErrorStatus write(const Message& msg, WriteIterator& iter, std::size_t len) const
    {
        Field field;
        auto es = field.write(iter, len);
        if (es != ErrorStatus::Success) {
            return es;
        }
        return m_next.write(msg, iter, len - field.length());
    }

    std::size_t length(const TMessage& msg) const
    {
        return Field().length() + m_next.length(msg);
    }

private:
    TNext m_next;
};
} // namespace comms
```

Note, that the value of the `SYNC` prefix is expected to be equal to the value of the default constructed `TField` field type. The default construction value may be set using `comms::option::DefaultNumValue` option described in [Generalising Fields Implementation](/comms-protocols-cpp/head-2/fields.md) chapter.

For example, 2 bytes synchronisation prefix `0xab 0xcd` with big endian serialisation may be defined as:

```cpp
using CommonFieldBase = comms::Field<false>; // big endian serialisation base
using SyncPrefixField = 
    comms::IntValueField<
        CommonFieldBase,
        std::uint16_t,
        comms::option::DefaultNumValue<0xabcd>
    >;
```
