~samwhited/xmpp

9de4741175d45b83a633236062ac812886548e05 — Sam Whited 5 years ago dca1827
Add unsafe (quick) Jid constructors

Also add some benchmarks and a Makefile to make running them easier

Fixes #3
3 files changed, 80 insertions(+), 7 deletions(-)

A Makefile
A benchmark_test.go
M jid.go
A Makefile => Makefile +13 -0
@@ 0,0 1,13 @@
.SILENT:

.PHONY: test
test:
	go test

.PHONY: benchmark
benchmark:
	go test -bench . -benchmem -run 'Benchmark.*'

.PHONY: build
build:
	go build

A benchmark_test.go => benchmark_test.go +33 -0
@@ 0,0 1,33 @@
// Copyright 2014 Sam Whited.
// Use of this source code is governed by the BSD 2-clause license that can be
// found in the LICENSE file.

package jid

import (
	"testing"
)

func BenchmarkJidFromString(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromString("user@example.com/resource")
	}
}

func BenchmarkJidFromStringUnsafe(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromStringUnsafe("user@example.com/resource")
	}
}

func BenchmarkJidFromParts(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromParts("user", "example.com", "resource")
	}
}

func BenchmarkJidFromPartsUnsafe(b *testing.B) {
	for i := 0; i < b.N; i++ {
		FromPartsUnsafe("user", "example.com", "resource")
	}
}

M jid.go => jid.go +34 -7
@@ 26,11 26,7 @@ type Jid struct {
	resourcepart string
}

// FromString constructs a new Jid object from the given string representation.
// The string may be any valid bare or full JID including domain names, IP
// literals, or hosts.
func FromString(s string) (*Jid, error) {

func partsFromString(s string) (string, string, string, error) {
	var localpart, domainpart, resourcepart string

	// RFC 7622 §3.1.  Fundamentals:


@@ 57,7 53,7 @@ func FromString(s string) (*Jid, error) {
		if len(parts) == 2 && parts[1] != "" {
			resourcepart = parts[1]
		} else {
			return nil, errors.New("The resourcepart must be larger than 0 bytes")
			return "", "", "", errors.New("The resourcepart must be larger than 0 bytes")
		}
	} else {
		resourcepart = ""


@@ 71,7 67,7 @@ func FromString(s string) (*Jid, error) {
	nolp := strings.SplitAfterN(norp, "@", 2)

	if nolp[0] == "@" {
		return nil, errors.New("The localpart must be larger than 0 bytes")
		return "", "", "", errors.New("The localpart must be larger than 0 bytes")
	}

	switch len(nolp) {


@@ 95,9 91,33 @@ func FromString(s string) (*Jid, error) {

	domainpart = strings.TrimSuffix(domainpart, ".")

	return localpart, domainpart, resourcepart, nil
}

// FromString constructs a new Jid object from the given string representation.
// The string may be any valid bare or full JID including domain names, IP
// literals, or hosts.
func FromString(s string) (*Jid, error) {
	localpart, domainpart, resourcepart, err := partsFromString(s)
	if err != nil {
		return nil, err
	}
	return FromParts(localpart, domainpart, resourcepart)
}

// FromStringUnsafe constructs a Jid without performing any verification on the
// input string. This is unsafe and should only be used for trusted, internal
// data (eg. a Jid from the database). External data (user input, a JID sent
// over the wire via an XMPP connection, etc.) should use the FromString method
// instead.
func FromStringUnsafe(s string) (*Jid, error) {
	localpart, domainpart, resourcepart, err := partsFromString(s)
	if err != nil {
		return nil, err
	}
	return FromPartsUnsafe(localpart, domainpart, resourcepart), nil
}

// FromParts constructs a new Jid object from the given localpart, domainpart,
// and resourcepart. The only required part is the domainpart ('example.net'
// and 'hostname' are valid Jids).


@@ 258,6 278,13 @@ func FromParts(localpart, domainpart, resourcepart string) (*Jid, error) {
	}, nil
}

// FromPartsUnsafe constructs a Jid from the given localpart, domainpart, and
// resourcepart without performing any verification on the
// input string.
func FromPartsUnsafe(localpart, domainpart, resourcepart string) *Jid {
	return &Jid{localpart, domainpart, resourcepart}
}

// Bare returns a copy of the Jid without a resourcepart. This is sometimes
// called a "bare" JID.
func (j *Jid) Bare() *Jid {