adding gres

This commit is contained in:
John
2019-08-13 21:06:11 +08:00
parent 162df6b250
commit 9ae537cafc
13 changed files with 118 additions and 32 deletions

View File

@ -8,5 +8,5 @@ import (
func main() {
gres.Dump()
g.Dump(gres.Scan("/", "*"))
g.Dump(gres.Scan("/r", "*", true))
}

File diff suppressed because one or more lines are too long

View File

@ -80,28 +80,28 @@ func (tree *AVLTree) Sets(data map[interface{}]interface{}) {
func (tree *AVLTree) Search(key interface{}) (value interface{}, found bool) {
tree.mu.RLock()
defer tree.mu.RUnlock()
if n := tree.doSearch(key); n != nil {
return n.Value, true
if node, found := tree.doSearch(key); found {
return node.Value, true
}
return nil, false
}
// doSearch searches the tree with given <key>.
// Second return parameter <found> is true if key was found, otherwise false.
func (tree *AVLTree) doSearch(key interface{}) *AVLTreeNode {
n := tree.root
for n != nil {
cmp := tree.comparator(key, n.Key)
func (tree *AVLTree) doSearch(key interface{}) (node *AVLTreeNode, found bool) {
node = tree.root
for node != nil {
cmp := tree.comparator(key, node.Key)
switch {
case cmp == 0:
return n
return node, true
case cmp < 0:
n = n.children[0]
node = node.children[0]
case cmp > 0:
n = n.children[1]
node = node.children[1]
}
}
return nil
return nil, false
}
// Get searches the node in the tree by <key> and returns its value or nil if key is not found in tree.
@ -122,8 +122,8 @@ func (tree *AVLTree) Get(key interface{}) (value interface{}) {
func (tree *AVLTree) doSetWithLockCheck(key interface{}, value interface{}) interface{} {
tree.mu.Lock()
defer tree.mu.Unlock()
if n := tree.doSearch(key); n != nil {
return n.Value
if node, found := tree.doSearch(key); found {
return node.Value
}
if f, ok := value.(func() interface{}); ok {
value = f()
@ -451,7 +451,8 @@ func (tree *AVLTree) IteratorAsc(f func(key, value interface{}) bool) {
func (tree *AVLTree) IteratorAscFrom(key interface{}, f func(key, value interface{}) bool) {
tree.mu.RLock()
defer tree.mu.RUnlock()
tree.doIteratorAsc(tree.doSearch(key), f)
node, _ := tree.doSearch(key)
tree.doIteratorAsc(node, f)
}
func (tree *AVLTree) doIteratorAsc(node *AVLTreeNode, f func(key, value interface{}) bool) {
@ -474,7 +475,8 @@ func (tree *AVLTree) IteratorDesc(f func(key, value interface{}) bool) {
func (tree *AVLTree) IteratorDescFrom(key interface{}, f func(key, value interface{}) bool) {
tree.mu.RLock()
defer tree.mu.RUnlock()
tree.doIteratorDesc(tree.doSearch(key), f)
node, _ := tree.doSearch(key)
tree.doIteratorDesc(node, f)
}
func (tree *AVLTree) doIteratorDesc(node *AVLTreeNode, f func(key, value interface{}) bool) {

View File

@ -142,7 +142,7 @@ func (tree *RedBlackTree) Get(key interface{}) (value interface{}) {
func (tree *RedBlackTree) doSetWithLockCheck(key interface{}, value interface{}) interface{} {
tree.mu.Lock()
defer tree.mu.Unlock()
if node := tree.doSearch(key); node != nil {
if node, found := tree.doSearch(key); found {
return node.Value
}
if f, ok := value.(func() interface{}); ok {
@ -253,8 +253,8 @@ func (tree *RedBlackTree) Contains(key interface{}) bool {
// doRemove removes the node from the tree by <key> without mutex.
func (tree *RedBlackTree) doRemove(key interface{}) (value interface{}) {
child := (*RedBlackTreeNode)(nil)
node := tree.doSearch(key)
if node == nil {
node, found := tree.doSearch(key)
if !found {
return
}
value = node.Value
@ -472,7 +472,8 @@ func (tree *RedBlackTree) IteratorAsc(f func(key, value interface{}) bool) {
func (tree *RedBlackTree) IteratorAscFrom(key interface{}, f func(key, value interface{}) bool) {
tree.mu.RLock()
defer tree.mu.RUnlock()
tree.doIteratorAsc(tree.doSearch(key), f)
node, _ := tree.doSearch(key)
tree.doIteratorAsc(node, f)
}
func (tree *RedBlackTree) doIteratorAsc(node *RedBlackTreeNode, f func(key, value interface{}) bool) {
@ -512,7 +513,8 @@ func (tree *RedBlackTree) IteratorDesc(f func(key, value interface{}) bool) {
func (tree *RedBlackTree) IteratorDescFrom(key interface{}, f func(key, value interface{}) bool) {
tree.mu.RLock()
defer tree.mu.RUnlock()
tree.doIteratorDesc(tree.doSearch(key), f)
node, _ := tree.doSearch(key)
tree.doIteratorDesc(node, f)
}
func (tree *RedBlackTree) doIteratorDesc(node *RedBlackTreeNode, f func(key, value interface{}) bool) {
@ -570,8 +572,8 @@ func (tree *RedBlackTree) Print() {
func (tree *RedBlackTree) Search(key interface{}) (value interface{}, found bool) {
tree.mu.RLock()
defer tree.mu.RUnlock()
node := tree.doSearch(key)
if node != nil {
node, found := tree.doSearch(key)
if found {
return node.Value, true
}
return nil, false
@ -629,20 +631,20 @@ func (tree *RedBlackTree) output(node *RedBlackTreeNode, prefix string, isTail b
// doSearch searches the tree with given <key> without mutex.
// It returns the node if found or otherwise nil.
func (tree *RedBlackTree) doSearch(key interface{}) *RedBlackTreeNode {
node := tree.root
func (tree *RedBlackTree) doSearch(key interface{}) (node *RedBlackTreeNode, found bool) {
node = tree.root
for node != nil {
compare := tree.comparator(key, node.Key)
switch {
case compare == 0:
return node
return node, true
case compare < 0:
node = node.left
case compare > 0:
node = node.right
}
}
return nil
return node, false
}
func (node *RedBlackTreeNode) grandparent() *RedBlackTreeNode {

View File

@ -20,21 +20,45 @@ func init() {
)
var (
// Default resource object.
defaultResource = New()
)
// Add unpacks and adds the <content> into the default resource object.
// The unnecessary parameter <prefix> indicates the prefix
// for each file storing into current resource object.
func Add(content []byte, prefix ...string) error {
return defaultResource.Add(content, prefix...)
}
// Load loads, unpacks and adds the data from <path> into the default resource object.
// The unnecessary parameter <prefix> indicates the prefix
// for each file storing into current resource object.
func Load(path string, prefix ...string) error {
return defaultResource.Load(path, prefix...)
}
// Get returns the file with given path.
func Get(path string) *File {
return defaultResource.Get(path)
}
// Contains checks whether the <path> exists in the default resource object.
func Contains(path string) bool {
return defaultResource.Contains(path)
}
// Scan returns the files under the given path, the parameter <path> should be a folder type.
//
// The pattern parameter <pattern> supports multiple file name patterns,
// using the ',' symbol to separate multiple patterns.
//
// It scans directory recursively if given parameter <recursive> is true.
func Scan(path string, pattern string, recursive ...bool) []*File {
return defaultResource.Scan(path, pattern, recursive...)
}
// Dump prints the files of the default resource object.
func Dump() {
defaultResource.Dump()
}

View File

@ -9,6 +9,7 @@ package gres
import (
"archive/zip"
"bytes"
"encoding/json"
"io"
"os"
)
@ -46,3 +47,13 @@ func (f *File) Content() ([]byte, error) {
func (f *File) FileInfo() os.FileInfo {
return f.zipFile.FileInfo()
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (f *File) MarshalJSON() ([]byte, error) {
info := f.FileInfo()
return json.Marshal(map[string]interface{}{
"name": f.Name(),
"size": info.Size(),
"time": info.ModTime(),
})
}

View File

@ -16,6 +16,9 @@ import (
"github.com/gogf/gf/os/gfile"
)
// Pack packs the path specified by <srcPath> into bytes.
// The unnecessary parameter <keyPrefix> indicates the prefix for each file
// packed into the result bytes.
func Pack(srcPath string, keyPrefix ...string) ([]byte, error) {
buffer := bytes.NewBuffer(nil)
err := gcompress.ZipPathWriter(srcPath, buffer, keyPrefix...)
@ -25,6 +28,9 @@ func Pack(srcPath string, keyPrefix ...string) ([]byte, error) {
return buffer.Bytes(), nil
}
// PackToFile packs the path specified by <srcPath> to target file <dstPath>.
// The unnecessary parameter <keyPrefix> indicates the prefix for each file
// packed into the result bytes.
func PackToFile(srcPath, dstPath string, keyPrefix ...string) error {
data, err := Pack(srcPath, keyPrefix...)
if err != nil {
@ -33,6 +39,11 @@ func PackToFile(srcPath, dstPath string, keyPrefix ...string) error {
return gfile.PutBytes(dstPath, data)
}
// PackToGoFile packs the path specified by <srcPath> to target go file <goFilePath>
// with given package name <pkgName>.
//
// The unnecessary parameter <keyPrefix> indicates the prefix for each file
// packed into the result bytes.
func PackToGoFile(srcPath, goFilePath, pkgName string, keyPrefix ...string) error {
data, err := Pack(srcPath, keyPrefix...)
if err != nil {
@ -43,6 +54,7 @@ func PackToGoFile(srcPath, goFilePath, pkgName string, keyPrefix ...string) erro
)
}
// Unpack unpacks the content specified by <path> to []*File.
func Unpack(path string) ([]*File, error) {
realPath, err := gfile.Search(path)
if err != nil {
@ -51,6 +63,7 @@ func Unpack(path string) ([]*File, error) {
return UnpackContent(gfile.GetBytes(realPath))
}
// UnpackContent unpacks the content to []*File.
func UnpackContent(content []byte) ([]*File, error) {
reader, err := zip.NewReader(bytes.NewReader(content), int64(len(content)))
if err != nil {

View File

@ -23,6 +23,7 @@ const (
gDEFAULT_TREE_M = 100
)
// New creates and returns a new resource object.
func New() *Resource {
return &Resource{
tree: gtree.NewBTree(gDEFAULT_TREE_M, func(v1, v2 interface{}) int {
@ -31,6 +32,9 @@ func New() *Resource {
}
}
// Add unpacks and adds the <content> into current resource object.
// The unnecessary parameter <prefix> indicates the prefix
// for each file storing into current resource object.
func (r *Resource) Add(content []byte, prefix ...string) error {
files, err := UnpackContent(content)
if err != nil {
@ -46,6 +50,9 @@ func (r *Resource) Add(content []byte, prefix ...string) error {
return nil
}
// Load loads, unpacks and adds the data from <path> into current resource object.
// The unnecessary parameter <prefix> indicates the prefix
// for each file storing into current resource object.
func (r *Resource) Load(path string, prefix ...string) error {
realPath, err := gfile.Search(path)
if err != nil {
@ -54,6 +61,7 @@ func (r *Resource) Load(path string, prefix ...string) error {
return r.Add(gfile.GetBytes(realPath), prefix...)
}
// Get returns the file with given path.
func (r *Resource) Get(path string) *File {
result := r.tree.Get(path)
if result != nil {
@ -62,6 +70,17 @@ func (r *Resource) Get(path string) *File {
return nil
}
// Contains checks whether the <path> exists in current resource object.
func (r *Resource) Contains(path string) bool {
return r.Get(path) != nil
}
// Scan returns the files under the given path, the parameter <path> should be a folder type.
//
// The pattern parameter <pattern> supports multiple file name patterns,
// using the ',' symbol to separate multiple patterns.
//
// It scans directory recursively if given parameter <recursive> is true.
func (r *Resource) Scan(path string, pattern string, recursive ...bool) []*File {
if path != "/" {
path = strings.TrimRight(path, "/\\")
@ -80,7 +99,7 @@ func (r *Resource) Scan(path string, pattern string, recursive ...bool) []*File
}
if len(recursive) == 0 || !recursive[0] {
if strings.IndexByte(name[length:], '/') != -1 {
return false
return true
}
}
for _, p := range patterns {
@ -94,10 +113,11 @@ func (r *Resource) Scan(path string, pattern string, recursive ...bool) []*File
return files
}
// Dump prints the files of current resource object.
func (r *Resource) Dump() {
r.tree.Iterator(func(key, value interface{}) bool {
fmt.Printf("%7s %s\n", gfile.FormatSize(value.(*File).FileInfo().Size()), key)
return true
})
fmt.Printf("TOTAL %d FILES", r.tree.Size())
fmt.Printf("TOTAL FILES: %d\n", r.tree.Size())
}

View File

@ -7,11 +7,12 @@
package gres_test
import (
"testing"
"github.com/gogf/gf/debug/gdebug"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/os/gres"
"github.com/gogf/gf/test/gtest"
"testing"
)
func Test_Export(t *testing.T) {
@ -19,7 +20,7 @@ func Test_Export(t *testing.T) {
srcPath := gfile.Dir(gdebug.CallerFilePath()) + "/testdata/files"
goFilePath := gfile.Dir(gdebug.CallerFilePath()) + "/testdata/testdata.go"
pkgName := "testdata"
err := gres.Export(srcPath, goFilePath, pkgName)
err := gres.PackToGoFile(srcPath, goFilePath, pkgName)
gtest.Assert(err, nil)
})
}

View File

@ -0,0 +1,4 @@
* {
font-size: 32px;
text-align: center;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,9 @@
<html>
<head>
<link rel="stylesheet" href="/css/style.css" type="text/css" />
</head>
<body>
<div><img src="image/logo.png"></div>
This is the index from gres.
</body>
</html>

File diff suppressed because one or more lines are too long