Create & Init Project...
This commit is contained in:
commit
0c567a6c8a
28
.gitignore
vendored
Normal file
28
.gitignore
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# ---> Go
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
/vendor
|
||||||
|
main
|
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM golang:alpine AS build
|
||||||
|
|
||||||
|
WORKDIR /go/src/github.com/yumc.pw/cloud/html2pic
|
||||||
|
ADD . .
|
||||||
|
RUN go build -o main
|
||||||
|
|
||||||
|
FROM alpine:edge
|
||||||
|
LABEL maintainer="MiaoWoo<admin@yumc.pw>"
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
WORKDIR /root
|
||||||
|
RUN apk add --no-cache ca-certificates
|
||||||
|
|
||||||
|
COPY --from=build /go/src/github.com/yumc.pw/cloud/html2pic/main ./main
|
||||||
|
ADD lib /root/lib
|
||||||
|
|
||||||
|
CMD ./main -lib /root/lib
|
BIN
lib/phantomjs
Executable file
BIN
lib/phantomjs
Executable file
Binary file not shown.
138
lib/screenshot.js
Normal file
138
lib/screenshot.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
var page = require('webpage').create(),
|
||||||
|
system = require('system'),
|
||||||
|
isDev = false,
|
||||||
|
reRunNum = 2,
|
||||||
|
resourceError = null;
|
||||||
|
if (system.args.length < 3) {
|
||||||
|
phantom.exit(1);
|
||||||
|
}
|
||||||
|
if (system.args[3]) {
|
||||||
|
isDev = true;
|
||||||
|
}
|
||||||
|
if (isDev) {
|
||||||
|
console.log(navigator.userAgent);
|
||||||
|
var s = (new Date()).getTime();
|
||||||
|
page.onConsoleMessage = function (msg) {
|
||||||
|
console.log(msg);
|
||||||
|
};
|
||||||
|
page.onError = function (msg, trace) {
|
||||||
|
console.log(msg + ';;errInfo' + JSON.stringify(trace));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log = function () {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
page.onResourceError = function (error) {
|
||||||
|
if (error.url == system.args[1]) {
|
||||||
|
console.log('pageLoadError:' + JSON.stringify(error));
|
||||||
|
resourceError = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_run();
|
||||||
|
setTimeout(function () {
|
||||||
|
console.log('pageTimeOut');
|
||||||
|
phantom.exit(2);
|
||||||
|
}, 20000)
|
||||||
|
|
||||||
|
function _run() {
|
||||||
|
page.open(system.args[1], function (status) {
|
||||||
|
if (status == 'fail') {
|
||||||
|
if (!_reRun()) {
|
||||||
|
phantom.exit(2);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var staticWaitNum = 10, pageWaitNum = 15, cd = 200, over, resources = {}, start = false, initRender = false;
|
||||||
|
|
||||||
|
page.onResourceRequested = function (request) {
|
||||||
|
if (!start) {
|
||||||
|
start = true;
|
||||||
|
}
|
||||||
|
resources[request.id + ''] = 0;
|
||||||
|
console.log('request -' + request.id + ':' + request.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
page.onResourceReceived = function (response) {
|
||||||
|
if (!start) {
|
||||||
|
start = true;
|
||||||
|
}
|
||||||
|
if (response.stage == "end") {
|
||||||
|
delete resources[response.id + ''];
|
||||||
|
console.log('response-' + response.id + ':' + response.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initOver() {
|
||||||
|
clearTimeout(over);
|
||||||
|
over = setTimeout(function () {
|
||||||
|
console.log('time:' + ((new Date()).getTime() - s) + '---resources' + JSON.stringify(resources));
|
||||||
|
if (resourceError != null && resourceError.status != 200) {
|
||||||
|
phantom.exit(3);
|
||||||
|
}
|
||||||
|
if (!initRender) {
|
||||||
|
console.log('initRender');
|
||||||
|
initRender = true;
|
||||||
|
page.render(system.args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!start) {
|
||||||
|
if (pageWaitNum-- > 0) {
|
||||||
|
console.log('pageWaitNum:' + pageWaitNum);
|
||||||
|
initOver();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (!_reRun()) {
|
||||||
|
_render();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var keys = _keys(resources), k;
|
||||||
|
for (var i in keys) {
|
||||||
|
k = keys[i];
|
||||||
|
resources[k]++;
|
||||||
|
if (resources[k] > staticWaitNum) {
|
||||||
|
console.log('timeOver:' + k);
|
||||||
|
delete resources[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_keys(resources).length > 0) {
|
||||||
|
initOver();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_render();
|
||||||
|
}, cd);
|
||||||
|
}
|
||||||
|
|
||||||
|
initOver();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function _render() {
|
||||||
|
page.render(system.args[2]);
|
||||||
|
console.log('overTime:' + ((new Date()).getTime() - s));
|
||||||
|
phantom.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _reRun() {
|
||||||
|
if (reRunNum-- > 0) {
|
||||||
|
console.log('reRun');
|
||||||
|
_run();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _keys(m) {
|
||||||
|
var ks = [];
|
||||||
|
for (var k in m) {
|
||||||
|
if (m.hasOwnProperty(k)) {
|
||||||
|
ks.push(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ks;
|
||||||
|
}
|
43
main.go
Normal file
43
main.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"yumc.pw/cloud/html2pic/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
b := flag.String("b", ":8080", "Server Bind Address")
|
||||||
|
lib := flag.String("lib", "/root", "Set Phantomjs Root Path")
|
||||||
|
tempDir := flag.String("temp", os.TempDir(), "")
|
||||||
|
flag.Parse()
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
uid, _ := uuid.NewV4()
|
||||||
|
uuid := "html2pic-" + uid.String()
|
||||||
|
url, html := r.FormValue("url"), r.FormValue("html")
|
||||||
|
tempFile := *tempDir + "/" + uuid + ".html"
|
||||||
|
if html != "" {
|
||||||
|
ioutil.WriteFile(tempFile, []byte("<!DOCTYPE html><html lang=\"zh\"><head><meta charset=\"UTF-8\"></head><body style=\"margin: 0;padding: 0;\">"+html+"</body></html>"), os.ModeAppend)
|
||||||
|
url = "file://" + tempFile
|
||||||
|
defer os.Remove(tempFile)
|
||||||
|
}
|
||||||
|
if url == "" {
|
||||||
|
w.Write([]byte("Empty Url..."))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tempPic := *tempDir + "/" + uuid + ".png"
|
||||||
|
err := exec.Command(*lib+"/phantomjs", *lib+"/screenshot.js", url, tempPic).Run()
|
||||||
|
defer os.Remove(tempPic)
|
||||||
|
if err != nil {
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bytes, _ := ioutil.ReadFile(tempPic)
|
||||||
|
w.Write(bytes)
|
||||||
|
})
|
||||||
|
http.ListenAndServe(*b, nil)
|
||||||
|
}
|
244
uuid/g.go
Normal file
244
uuid/g.go
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Difference in 100-nanosecond intervals between
|
||||||
|
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
|
||||||
|
const epochStart = 122192928000000000
|
||||||
|
|
||||||
|
type epochFunc func() time.Time
|
||||||
|
type hwAddrFunc func() (net.HardwareAddr, error)
|
||||||
|
|
||||||
|
var (
|
||||||
|
global = newRFC4122Generator()
|
||||||
|
|
||||||
|
posixUID = uint32(os.Getuid())
|
||||||
|
posixGID = uint32(os.Getgid())
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewV1 returns UUID based on current timestamp and MAC address.
|
||||||
|
func NewV1() (UUID, error) {
|
||||||
|
return global.NewV1()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
|
||||||
|
func NewV2(domain byte) (UUID, error) {
|
||||||
|
return global.NewV2(domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
|
||||||
|
func NewV3(ns UUID, name string) UUID {
|
||||||
|
return global.NewV3(ns, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV4 returns random generated UUID.
|
||||||
|
func NewV4() (UUID, error) {
|
||||||
|
return global.NewV4()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
|
||||||
|
func NewV5(ns UUID, name string) UUID {
|
||||||
|
return global.NewV5(ns, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generator provides interface for generating UUIDs.
|
||||||
|
type Generator interface {
|
||||||
|
NewV1() (UUID, error)
|
||||||
|
NewV2(domain byte) (UUID, error)
|
||||||
|
NewV3(ns UUID, name string) UUID
|
||||||
|
NewV4() (UUID, error)
|
||||||
|
NewV5(ns UUID, name string) UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default generator implementation.
|
||||||
|
type rfc4122Generator struct {
|
||||||
|
clockSequenceOnce sync.Once
|
||||||
|
hardwareAddrOnce sync.Once
|
||||||
|
storageMutex sync.Mutex
|
||||||
|
|
||||||
|
rand io.Reader
|
||||||
|
|
||||||
|
epochFunc epochFunc
|
||||||
|
hwAddrFunc hwAddrFunc
|
||||||
|
lastTime uint64
|
||||||
|
clockSequence uint16
|
||||||
|
hardwareAddr [6]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRFC4122Generator() Generator {
|
||||||
|
return &rfc4122Generator{
|
||||||
|
epochFunc: time.Now,
|
||||||
|
hwAddrFunc: defaultHWAddrFunc,
|
||||||
|
rand: rand.Reader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV1 returns UUID based on current timestamp and MAC address.
|
||||||
|
func (g *rfc4122Generator) NewV1() (UUID, error) {
|
||||||
|
u := UUID{}
|
||||||
|
|
||||||
|
timeNow, clockSeq, err := g.getClockSequence()
|
||||||
|
if err != nil {
|
||||||
|
return Nil, err
|
||||||
|
}
|
||||||
|
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
|
||||||
|
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
|
||||||
|
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
|
||||||
|
binary.BigEndian.PutUint16(u[8:], clockSeq)
|
||||||
|
|
||||||
|
hardwareAddr, err := g.getHardwareAddr()
|
||||||
|
if err != nil {
|
||||||
|
return Nil, err
|
||||||
|
}
|
||||||
|
copy(u[10:], hardwareAddr)
|
||||||
|
|
||||||
|
u.SetVersion(V1)
|
||||||
|
u.SetVariant(VariantRFC4122)
|
||||||
|
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
|
||||||
|
func (g *rfc4122Generator) NewV2(domain byte) (UUID, error) {
|
||||||
|
u, err := g.NewV1()
|
||||||
|
if err != nil {
|
||||||
|
return Nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch domain {
|
||||||
|
case DomainPerson:
|
||||||
|
binary.BigEndian.PutUint32(u[:], posixUID)
|
||||||
|
case DomainGroup:
|
||||||
|
binary.BigEndian.PutUint32(u[:], posixGID)
|
||||||
|
}
|
||||||
|
|
||||||
|
u[9] = domain
|
||||||
|
|
||||||
|
u.SetVersion(V2)
|
||||||
|
u.SetVariant(VariantRFC4122)
|
||||||
|
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
|
||||||
|
func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID {
|
||||||
|
u := newFromHash(md5.New(), ns, name)
|
||||||
|
u.SetVersion(V3)
|
||||||
|
u.SetVariant(VariantRFC4122)
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV4 returns random generated UUID.
|
||||||
|
func (g *rfc4122Generator) NewV4() (UUID, error) {
|
||||||
|
u := UUID{}
|
||||||
|
if _, err := g.rand.Read(u[:]); err != nil {
|
||||||
|
return Nil, err
|
||||||
|
}
|
||||||
|
u.SetVersion(V4)
|
||||||
|
u.SetVariant(VariantRFC4122)
|
||||||
|
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
|
||||||
|
func (g *rfc4122Generator) NewV5(ns UUID, name string) UUID {
|
||||||
|
u := newFromHash(sha1.New(), ns, name)
|
||||||
|
u.SetVersion(V5)
|
||||||
|
u.SetVariant(VariantRFC4122)
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns epoch and clock sequence.
|
||||||
|
func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) {
|
||||||
|
var err error
|
||||||
|
g.clockSequenceOnce.Do(func() {
|
||||||
|
buf := make([]byte, 2)
|
||||||
|
if _, err = g.rand.Read(buf); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.clockSequence = binary.BigEndian.Uint16(buf)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.storageMutex.Lock()
|
||||||
|
defer g.storageMutex.Unlock()
|
||||||
|
|
||||||
|
timeNow := g.getEpoch()
|
||||||
|
// Clock didn't change since last UUID generation.
|
||||||
|
// Should increase clock sequence.
|
||||||
|
if timeNow <= g.lastTime {
|
||||||
|
g.clockSequence++
|
||||||
|
}
|
||||||
|
g.lastTime = timeNow
|
||||||
|
|
||||||
|
return timeNow, g.clockSequence, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns hardware address.
|
||||||
|
func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) {
|
||||||
|
var err error
|
||||||
|
g.hardwareAddrOnce.Do(func() {
|
||||||
|
if hwAddr, err := g.hwAddrFunc(); err == nil {
|
||||||
|
copy(g.hardwareAddr[:], hwAddr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize hardwareAddr randomly in case
|
||||||
|
// of real network interfaces absence.
|
||||||
|
if _, err = g.rand.Read(g.hardwareAddr[:]); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Set multicast bit as recommended by RFC 4122
|
||||||
|
g.hardwareAddr[0] |= 0x01
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
return g.hardwareAddr[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns difference in 100-nanosecond intervals between
|
||||||
|
// UUID epoch (October 15, 1582) and current time.
|
||||||
|
func (g *rfc4122Generator) getEpoch() uint64 {
|
||||||
|
return epochStart + uint64(g.epochFunc().UnixNano()/100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns UUID based on hashing of namespace UUID and name.
|
||||||
|
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
|
||||||
|
u := UUID{}
|
||||||
|
h.Write(ns[:])
|
||||||
|
h.Write([]byte(name))
|
||||||
|
copy(u[:], h.Sum(nil))
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns hardware address.
|
||||||
|
func defaultHWAddrFunc() (net.HardwareAddr, error) {
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if len(iface.HardwareAddr) >= 6 {
|
||||||
|
return iface.HardwareAddr, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return []byte{}, fmt.Errorf("uuid: no HW address found")
|
||||||
|
}
|
129
uuid/uuid.go
Normal file
129
uuid/uuid.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Size of a UUID in bytes.
|
||||||
|
const Size = 16
|
||||||
|
|
||||||
|
// UUID representation compliant with specification
|
||||||
|
// described in RFC 4122.
|
||||||
|
type UUID [Size]byte
|
||||||
|
|
||||||
|
// UUID versions
|
||||||
|
const (
|
||||||
|
_ byte = iota
|
||||||
|
V1
|
||||||
|
V2
|
||||||
|
V3
|
||||||
|
V4
|
||||||
|
V5
|
||||||
|
)
|
||||||
|
|
||||||
|
// UUID layout variants.
|
||||||
|
const (
|
||||||
|
VariantNCS byte = iota
|
||||||
|
VariantRFC4122
|
||||||
|
VariantMicrosoft
|
||||||
|
VariantFuture
|
||||||
|
)
|
||||||
|
|
||||||
|
// UUID DCE domains.
|
||||||
|
const (
|
||||||
|
DomainPerson = iota
|
||||||
|
DomainGroup
|
||||||
|
DomainOrg
|
||||||
|
)
|
||||||
|
|
||||||
|
// String parse helpers.
|
||||||
|
var (
|
||||||
|
urnPrefix = []byte("urn:uuid:")
|
||||||
|
byteGroups = []int{8, 4, 4, 4, 12}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nil is special form of UUID that is specified to have all
|
||||||
|
// 128 bits set to zero.
|
||||||
|
var Nil = UUID{}
|
||||||
|
|
||||||
|
// Equal returns true if u1 and u2 equals, otherwise returns false.
|
||||||
|
func Equal(u1 UUID, u2 UUID) bool {
|
||||||
|
return bytes.Equal(u1[:], u2[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version returns algorithm version used to generate UUID.
|
||||||
|
func (u UUID) Version() byte {
|
||||||
|
return u[6] >> 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variant returns UUID layout variant.
|
||||||
|
func (u UUID) Variant() byte {
|
||||||
|
switch {
|
||||||
|
case (u[8] >> 7) == 0x00:
|
||||||
|
return VariantNCS
|
||||||
|
case (u[8] >> 6) == 0x02:
|
||||||
|
return VariantRFC4122
|
||||||
|
case (u[8] >> 5) == 0x06:
|
||||||
|
return VariantMicrosoft
|
||||||
|
case (u[8] >> 5) == 0x07:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
return VariantFuture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns bytes slice representation of UUID.
|
||||||
|
func (u UUID) Bytes() []byte {
|
||||||
|
return u[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns canonical string representation of UUID:
|
||||||
|
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
|
||||||
|
func (u UUID) String() string {
|
||||||
|
buf := make([]byte, 36)
|
||||||
|
|
||||||
|
hex.Encode(buf[0:8], u[0:4])
|
||||||
|
buf[8] = '-'
|
||||||
|
hex.Encode(buf[9:13], u[4:6])
|
||||||
|
buf[13] = '-'
|
||||||
|
hex.Encode(buf[14:18], u[6:8])
|
||||||
|
buf[18] = '-'
|
||||||
|
hex.Encode(buf[19:23], u[8:10])
|
||||||
|
buf[23] = '-'
|
||||||
|
hex.Encode(buf[24:], u[10:])
|
||||||
|
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVersion sets version bits.
|
||||||
|
func (u *UUID) SetVersion(v byte) {
|
||||||
|
u[6] = (u[6] & 0x0f) | (v << 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVariant sets variant bits.
|
||||||
|
func (u *UUID) SetVariant(v byte) {
|
||||||
|
switch v {
|
||||||
|
case VariantNCS:
|
||||||
|
u[8] = (u[8]&(0xff>>1) | (0x00 << 7))
|
||||||
|
case VariantRFC4122:
|
||||||
|
u[8] = (u[8]&(0xff>>2) | (0x02 << 6))
|
||||||
|
case VariantMicrosoft:
|
||||||
|
u[8] = (u[8]&(0xff>>3) | (0x06 << 5))
|
||||||
|
case VariantFuture:
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
u[8] = (u[8]&(0xff>>3) | (0x07 << 5))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must is a helper that wraps a call to a function returning (UUID, error)
|
||||||
|
// and panics if the error is non-nil. It is intended for use in variable
|
||||||
|
// initializations such as
|
||||||
|
// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"));
|
||||||
|
func Must(u UUID, err error) UUID {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user