You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: read_xlog_page.go
    path of file: ./repos/wal-g/internal/walparser
    
    the code of the file until where you have to start completion: package walparser

import (
	"bytes"
	"fmt"
	"io"

	"github.com/pkg/errors"
	"github.com/wal-g/tracelog"
	"github.com/wal-g/wal-g/internal/walparser/parsingutil"
)

type ZeroPageHeaderError struct {
	error
}

func NewZeroPageHeaderError() error {
	return ZeroPageHeaderError{
		errors.New("page header contains only zeroes, " +
			"maybe it is a part .partial file or this page follow WAL-switch record")}
}

func (err ZeroPageHeaderError) Error() string {
	return fmt.Sprintf(tracelog.GetErrorFormatter(), err.error)
}

type InvalidPageHeaderError struct {
	error
    
func readXLogPageHeader(reader io.Reader) (*XLogPageHeader, error) {
	pageHeader := XLogPageHeader{}
	err := parsingutil.ParseMultipleFieldsFromReader([]parsingutil.FieldToParse{
		{Field: &pageHeader.Magic, Name: "magic"},
		{Field: &pageHeader.Info, Name: "info"},
		{Field: &pageHeader.TimeLineID, Name: "timeLineID"},
		{Field: &pageHeader.PageAddress, Name: "pageAddress"},
		{Field: &pageHeader.RemainingDataLen, Name: "remainingDataLen"},
	}, reader)
	if err != nil {
		return nil, err
	}
	if pageHeader.isZero() {
		return nil, NewZeroPageHeaderError()
	}

	if !pageHeader.IsValid() {
		return nil, NewInvalidPageHeaderError()
	}

	// read long header data from reader
	if pageHeader.IsLong() {
		err = readXLogLongPageHeaderData(reader)
		if err != nil {
			return nil, err
		}
	}

	return &pageHeader, nil
}