From c6e5a5210458f37ac157622c28bb6476fe6dfd46 Mon Sep 17 00:00:00 2001 From: jroam Date: Fri, 14 Jun 2019 23:47:00 +0800 Subject: [PATCH 01/19] add test file --- g/container/gqueue/gqueue_unit_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 g/container/gqueue/gqueue_unit_test.go diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go new file mode 100644 index 000000000..5d0a63369 --- /dev/null +++ b/g/container/gqueue/gqueue_unit_test.go @@ -0,0 +1,15 @@ +package gqueue_test +import ( + "testing" + "github.com/gogf/gf/g/container/gqueue" + "github.com/gogf/gf/g/test/gtest" +) + + +func TestQueue_Size(t *testing.T) { + q1:=gqueue.New(3) + q1.Push(1) + q1.Push(2) + q1.Push(3) + gtest.Assert(q1.Size(),3) +} From 142154c0df492ac815b11b634f27b7a4c82bdc11 Mon Sep 17 00:00:00 2001 From: jroam Date: Sat, 15 Jun 2019 18:35:36 +0800 Subject: [PATCH 02/19] add gqueue unit tests --- g/container/gqueue/gqueue_unit_test.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 5d0a63369..b6fe22191 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -1,15 +1,33 @@ package gqueue_test + import ( - "testing" "github.com/gogf/gf/g/container/gqueue" "github.com/gogf/gf/g/test/gtest" + "testing" ) func TestQueue_Size(t *testing.T) { - q1:=gqueue.New(3) + q1:=gqueue.New(2) + q1.Push(1) + q1.Push(2) + gtest.Assert(q1.Len(),2) +} + +func TestQueue_Pop(t *testing.T) { + q1:=gqueue.New() q1.Push(1) q1.Push(2) q1.Push(3) - gtest.Assert(q1.Size(),3) + i1:=q1.Pop() + gtest.Assert(i1,1) +} + +func TestQueue_Close(t *testing.T) { + q1:=gqueue.New() + q1.Push(1) + q1.Push(2) + gtest.Assert(q1.Size(),2) + q1.Close() + gtest.Assert(q1.Size(),2) } From ab38b709b2ecc8370f930b711d4cef9127877086 Mon Sep 17 00:00:00 2001 From: jroam Date: Sat, 15 Jun 2019 18:44:22 +0800 Subject: [PATCH 03/19] add gqueue tests --- g/container/gqueue/gqueue_unit_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index b6fe22191..d5f76f4fc 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -6,28 +6,28 @@ import ( "testing" ) - -func TestQueue_Size(t *testing.T) { - q1:=gqueue.New(2) +func TestQueue_Len(t *testing.T) { + q1 := gqueue.New(2) q1.Push(1) q1.Push(2) - gtest.Assert(q1.Len(),2) + gtest.Assert(q1.Len(), 2) + gtest.Assert(q1.Size(), 2) } func TestQueue_Pop(t *testing.T) { - q1:=gqueue.New() + q1 := gqueue.New() q1.Push(1) q1.Push(2) q1.Push(3) - i1:=q1.Pop() - gtest.Assert(i1,1) + i1 := q1.Pop() + gtest.Assert(i1, 1) } func TestQueue_Close(t *testing.T) { - q1:=gqueue.New() + q1 := gqueue.New() q1.Push(1) q1.Push(2) - gtest.Assert(q1.Size(),2) + gtest.Assert(q1.Len(), 2) q1.Close() - gtest.Assert(q1.Size(),2) + gtest.Assert(q1.Len(), 2) } From a7f15a4e00a178f8308e6db9c4497fb07d3b5f5e Mon Sep 17 00:00:00 2001 From: jroam Date: Sat, 15 Jun 2019 21:40:36 +0800 Subject: [PATCH 04/19] change gqueue unit tests --- g/container/gqueue/gqueue_unit_test.go | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index d5f76f4fc..2e187dab9 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -7,27 +7,17 @@ import ( ) func TestQueue_Len(t *testing.T) { - q1 := gqueue.New(2) + q1 := gqueue.New() q1.Push(1) - q1.Push(2) + q1.Push(5) gtest.Assert(q1.Len(), 2) - gtest.Assert(q1.Size(), 2) } func TestQueue_Pop(t *testing.T) { q1 := gqueue.New() q1.Push(1) q1.Push(2) - q1.Push(3) - i1 := q1.Pop() + i1:=q1.Pop() gtest.Assert(i1, 1) } -func TestQueue_Close(t *testing.T) { - q1 := gqueue.New() - q1.Push(1) - q1.Push(2) - gtest.Assert(q1.Len(), 2) - q1.Close() - gtest.Assert(q1.Len(), 2) -} From 677549ec1510d37beedb5f8fe6f950ae4e5fc433 Mon Sep 17 00:00:00 2001 From: jroam Date: Sun, 16 Jun 2019 16:41:12 +0800 Subject: [PATCH 05/19] add some gqueue tests --- g/container/gqueue/gqueue_unit_test.go | 47 +++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 2e187dab9..a99fda022 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -7,17 +7,54 @@ import ( ) func TestQueue_Len(t *testing.T) { - q1 := gqueue.New() - q1.Push(1) - q1.Push(5) - gtest.Assert(q1.Len(), 2) + q1 := gqueue.New(300) + for i := 0; i < 200; i++ { + q1.Push(i) + } + gtest.Assert(q1.Len(), 200) } func TestQueue_Pop(t *testing.T) { q1 := gqueue.New() + q1.Push(1) q1.Push(2) - i1:=q1.Pop() + i1 := q1.Pop() gtest.Assert(i1, 1) + q1.Close() + i1 = q1.Pop() + gtest.Assert(i1, 2) + + maxs := 12 + q2 := gqueue.New(maxs) + for i := 0; i < maxs; i++ { + q2.Push(i) + } + + i3 := q2.Pop() + gtest.Assert(i3, 0) + } +func TestQueue_Pop2(t *testing.T) { + + maxs := 14 + q2 := gqueue.New(maxs) + for i := 1; i < maxs; i++ { + q2.Push(i) + } + i3 := q2.Pop() + gtest.Assert(i3, 1) + +} + +func TestQueue_Close(t *testing.T) { + q1 := gqueue.New() + q1.Push(1) + q1.Push(2) + gtest.Assert(q1.Len(), 2) + + q1.Close() + gtest.Assert(q1.Len(), 2) + +} From 78b0cae892fd1e38286f832045457a02a1d0d94b Mon Sep 17 00:00:00 2001 From: jroam Date: Sun, 16 Jun 2019 22:05:15 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E5=85=88=E5=8F=96=E6=B6=88=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gqueue/gqueue_unit_test.go | 60 -------------------------- 1 file changed, 60 deletions(-) delete mode 100644 g/container/gqueue/gqueue_unit_test.go diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go deleted file mode 100644 index a99fda022..000000000 --- a/g/container/gqueue/gqueue_unit_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package gqueue_test - -import ( - "github.com/gogf/gf/g/container/gqueue" - "github.com/gogf/gf/g/test/gtest" - "testing" -) - -func TestQueue_Len(t *testing.T) { - q1 := gqueue.New(300) - for i := 0; i < 200; i++ { - q1.Push(i) - } - gtest.Assert(q1.Len(), 200) -} - -func TestQueue_Pop(t *testing.T) { - q1 := gqueue.New() - - q1.Push(1) - q1.Push(2) - i1 := q1.Pop() - gtest.Assert(i1, 1) - q1.Close() - i1 = q1.Pop() - gtest.Assert(i1, 2) - - maxs := 12 - q2 := gqueue.New(maxs) - for i := 0; i < maxs; i++ { - q2.Push(i) - } - - i3 := q2.Pop() - gtest.Assert(i3, 0) - -} - -func TestQueue_Pop2(t *testing.T) { - - maxs := 14 - q2 := gqueue.New(maxs) - for i := 1; i < maxs; i++ { - q2.Push(i) - } - i3 := q2.Pop() - gtest.Assert(i3, 1) - -} - -func TestQueue_Close(t *testing.T) { - q1 := gqueue.New() - q1.Push(1) - q1.Push(2) - gtest.Assert(q1.Len(), 2) - - q1.Close() - gtest.Assert(q1.Len(), 2) - -} From 168c08a6f6ccd6d30af96cc3dcae0b89298714cf Mon Sep 17 00:00:00 2001 From: jroam Date: Sun, 16 Jun 2019 22:55:07 +0800 Subject: [PATCH 07/19] Create gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 g/container/gqueue/gqueue_unit_test.go diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go new file mode 100644 index 000000000..a99fda022 --- /dev/null +++ b/g/container/gqueue/gqueue_unit_test.go @@ -0,0 +1,60 @@ +package gqueue_test + +import ( + "github.com/gogf/gf/g/container/gqueue" + "github.com/gogf/gf/g/test/gtest" + "testing" +) + +func TestQueue_Len(t *testing.T) { + q1 := gqueue.New(300) + for i := 0; i < 200; i++ { + q1.Push(i) + } + gtest.Assert(q1.Len(), 200) +} + +func TestQueue_Pop(t *testing.T) { + q1 := gqueue.New() + + q1.Push(1) + q1.Push(2) + i1 := q1.Pop() + gtest.Assert(i1, 1) + q1.Close() + i1 = q1.Pop() + gtest.Assert(i1, 2) + + maxs := 12 + q2 := gqueue.New(maxs) + for i := 0; i < maxs; i++ { + q2.Push(i) + } + + i3 := q2.Pop() + gtest.Assert(i3, 0) + +} + +func TestQueue_Pop2(t *testing.T) { + + maxs := 14 + q2 := gqueue.New(maxs) + for i := 1; i < maxs; i++ { + q2.Push(i) + } + i3 := q2.Pop() + gtest.Assert(i3, 1) + +} + +func TestQueue_Close(t *testing.T) { + q1 := gqueue.New() + q1.Push(1) + q1.Push(2) + gtest.Assert(q1.Len(), 2) + + q1.Close() + gtest.Assert(q1.Len(), 2) + +} From 5b71e927762c58c1e9288ecc22940a5ace2dd938 Mon Sep 17 00:00:00 2001 From: jroam Date: Sun, 16 Jun 2019 23:24:03 +0800 Subject: [PATCH 08/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index a99fda022..81143df1d 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -7,11 +7,16 @@ import ( ) func TestQueue_Len(t *testing.T) { - q1 := gqueue.New(300) - for i := 0; i < 200; i++ { - q1.Push(i) + maxs := 100 + for n := 10; n < maxs; n++ { + q1 := gqueue.New(maxs) + for i := 0; i < maxs; i++ { + q1.Push(i) + + } + gtest.Assert(q1.Len(), maxs) } - gtest.Assert(q1.Len(), 200) + } func TestQueue_Pop(t *testing.T) { @@ -36,18 +41,6 @@ func TestQueue_Pop(t *testing.T) { } -func TestQueue_Pop2(t *testing.T) { - - maxs := 14 - q2 := gqueue.New(maxs) - for i := 1; i < maxs; i++ { - q2.Push(i) - } - i3 := q2.Pop() - gtest.Assert(i3, 1) - -} - func TestQueue_Close(t *testing.T) { q1 := gqueue.New() q1.Push(1) From 0ab60cb770f49178ba840b56aaab97ecbb25640b Mon Sep 17 00:00:00 2001 From: jroam Date: Sun, 16 Jun 2019 23:26:49 +0800 Subject: [PATCH 09/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 81143df1d..d0ae9d7c4 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -12,7 +12,6 @@ func TestQueue_Len(t *testing.T) { q1 := gqueue.New(maxs) for i := 0; i < maxs; i++ { q1.Push(i) - } gtest.Assert(q1.Len(), maxs) } From 97d2b9e1f97c2d953fbd255a4258713c4c305f1e Mon Sep 17 00:00:00 2001 From: jroam Date: Mon, 17 Jun 2019 11:04:56 +0800 Subject: [PATCH 10/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index d0ae9d7c4..6117efd5c 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -15,12 +15,10 @@ func TestQueue_Len(t *testing.T) { } gtest.Assert(q1.Len(), maxs) } - } func TestQueue_Pop(t *testing.T) { q1 := gqueue.New() - q1.Push(1) q1.Push(2) i1 := q1.Pop() @@ -37,7 +35,6 @@ func TestQueue_Pop(t *testing.T) { i3 := q2.Pop() gtest.Assert(i3, 0) - } func TestQueue_Close(t *testing.T) { From fd4843c3a1531d38d06a6be2e0d5df9fbed5ac4c Mon Sep 17 00:00:00 2001 From: jroam Date: Mon, 17 Jun 2019 11:31:03 +0800 Subject: [PATCH 11/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 6117efd5c..19b4a0405 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -21,6 +21,8 @@ func TestQueue_Pop(t *testing.T) { q1 := gqueue.New() q1.Push(1) q1.Push(2) + q1.Push(3) + q1.Push(4) i1 := q1.Pop() gtest.Assert(i1, 1) q1.Close() From 53b5de330eb3c6303e7768097d9496f64fb03c6d Mon Sep 17 00:00:00 2001 From: jroam Date: Mon, 17 Jun 2019 11:40:40 +0800 Subject: [PATCH 12/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 19b4a0405..eb8908a14 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -25,18 +25,7 @@ func TestQueue_Pop(t *testing.T) { q1.Push(4) i1 := q1.Pop() gtest.Assert(i1, 1) - q1.Close() - i1 = q1.Pop() - gtest.Assert(i1, 2) - maxs := 12 - q2 := gqueue.New(maxs) - for i := 0; i < maxs; i++ { - q2.Push(i) - } - - i3 := q2.Pop() - gtest.Assert(i3, 0) } func TestQueue_Close(t *testing.T) { @@ -44,8 +33,5 @@ func TestQueue_Close(t *testing.T) { q1.Push(1) q1.Push(2) gtest.Assert(q1.Len(), 2) - q1.Close() - gtest.Assert(q1.Len(), 2) - } From 9fad898ee32ad8d6e10b3917b2d0193205232e31 Mon Sep 17 00:00:00 2001 From: jroam Date: Mon, 17 Jun 2019 22:03:41 +0800 Subject: [PATCH 13/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 8b947ca75..085c55cfc 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -53,4 +53,6 @@ func TestQueue_Close(t *testing.T) { q1.Push(2) gtest.Assert(q1.Len(), 2) q1.Close() + q1.Pop() + gtest.Assert(q1.Len(), 2) } From fe795d49f3cb9d5142b2aea30f1ca303c68fcb3b Mon Sep 17 00:00:00 2001 From: jroam Date: Mon, 17 Jun 2019 22:46:36 +0800 Subject: [PATCH 14/19] fix gfile test of a bug fix gfile test of bug --- g/os/gfile/gfile_z_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/g/os/gfile/gfile_z_test.go b/g/os/gfile/gfile_z_test.go index c0315f9f5..b7d438434 100644 --- a/g/os/gfile/gfile_z_test.go +++ b/g/os/gfile/gfile_z_test.go @@ -337,9 +337,7 @@ func TestCopy(t *testing.T) { defer delTestFiles(topath) gtest.Assert(gfile.IsFile(testpath()+topath), true) - gtest.AssertNE(gfile.Copy("", ""), nil) - }) } @@ -365,7 +363,7 @@ func TestDirNames(t *testing.T) { readlist, err = gfile.DirNames(testpath() + paths) gtest.Assert(err, nil) - gtest.Assert(havelist, readlist) + gtest.AssertIN(readlist, havelist) _, err = gfile.DirNames("") gtest.AssertNE(err, nil) @@ -653,8 +651,8 @@ func TestMkdir(t *testing.T) { func TestStat(t *testing.T) { gtest.Case(t, func() { var ( - tpath1 = "/testfile_t1.txt" - tpath2 = "./testfile_t1_no.txt" + tpath1 = "/testfile_t1.txt" + tpath2 = "./testfile_t1_no.txt" err error fileiofo os.FileInfo ) From 28d25e7812fb64c935f9a0af6f26d9e7be1840ce Mon Sep 17 00:00:00 2001 From: jroam Date: Mon, 17 Jun 2019 23:16:22 +0800 Subject: [PATCH 15/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 085c55cfc..8b947ca75 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -53,6 +53,4 @@ func TestQueue_Close(t *testing.T) { q1.Push(2) gtest.Assert(q1.Len(), 2) q1.Close() - q1.Pop() - gtest.Assert(q1.Len(), 2) } From 2a0eae897556239e2df4c7a14d26a9730f56344c Mon Sep 17 00:00:00 2001 From: zhangxinxiang Date: Tue, 18 Jun 2019 04:07:35 +0800 Subject: [PATCH 16/19] gaes encryption and decryption add CFB mode --- g/crypto/gaes/gaes.go | 63 ++++++++++++++++++++++++++++++++++++++ g/crypto/gaes/gaes_test.go | 22 +++++++++++++ 2 files changed, 85 insertions(+) diff --git a/g/crypto/gaes/gaes.go b/g/crypto/gaes/gaes.go index 14f34f44b..40d381f9f 100644 --- a/g/crypto/gaes/gaes.go +++ b/g/crypto/gaes/gaes.go @@ -98,3 +98,66 @@ func PKCS5UnPadding(src []byte, blockSize int) ([]byte, error) { return src[:(length - unpadding)], nil } + +/** + * AES加密, 使用CFB模式. + * 注意key必须为16/24/32位长度,padding返回补位长度,iv初始化向量为非必需参数 + * author: zseeker + * date: 2019-06-18 + */ +func EncryptCFB(plainText []byte, key []byte, padding *int, iv ...[]byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + blockSize := block.BlockSize() + plainText, *padding = ZeroPadding(plainText, blockSize) //补位0 + ivValue := ([]byte)(nil) + if len(iv) > 0 { + ivValue = iv[0] + } else { + ivValue = []byte(ivDefValue) + } + stream := cipher.NewCFBEncrypter(block, ivValue) + cipherText := make([]byte, len(plainText)) + stream.XORKeyStream(cipherText, plainText) + return cipherText, nil +} + +/** + * AES解密, 使用CFB模式. + * 注意key必须为16/24/32位长度,unpadding为去补位长度,iv初始化向量为非必需参数 + * author: zseeker + * date: 2019-06-18 + */ +func DecryptCFB(cipherText []byte, key []byte, unpadding int, iv ...[]byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + if len(cipherText) < aes.BlockSize { + return nil, errors.New("cipherText too short") + } + ivValue := ([]byte)(nil) + if len(iv) > 0 { + ivValue = iv[0] + } else { + ivValue = []byte(ivDefValue) + } + stream := cipher.NewCFBDecrypter(block, ivValue) + plainText := make([]byte, len(cipherText)) + stream.XORKeyStream(plainText, cipherText) + plainText = ZeroUnPadding(plainText, unpadding) //去补位0 + return plainText, nil +} + +func ZeroPadding(ciphertext []byte, blockSize int) ([]byte, int) { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(0)}, padding) + return append(ciphertext, padtext...), padding +} + +func ZeroUnPadding(plaintext []byte, unpadding int) []byte { + length := len(plaintext) + return plaintext[:(length - unpadding)] +} \ No newline at end of file diff --git a/g/crypto/gaes/gaes_test.go b/g/crypto/gaes/gaes_test.go index 57f307a6e..119900065 100644 --- a/g/crypto/gaes/gaes_test.go +++ b/g/crypto/gaes/gaes_test.go @@ -32,6 +32,10 @@ var ( keys = []byte("12345678912345678912345678912346") key_err = []byte("1234") key_32_err = []byte("1234567891234567891234567891234 ") + + // cfb模式blockSize补位长度, add by zseeker + padding_size = 16 - len(content) + content_16_cfb, _ = gbase64.Decode("oSmget3aBDT1nJnBp8u6kA==") ) func TestEncrypt(t *testing.T) { @@ -125,3 +129,21 @@ func TestPKCS5UnPaddingErr(t *testing.T) { gtest.AssertNE(err, nil) }) } + +func TestEncryptCFB(t *testing.T) { + gtest.Case(t, func() { + var padding int = 0 + data, err := gaes.EncryptCFB(content, key_16, &padding, iv) + gtest.Assert(err, nil) + gtest.Assert(padding, padding_size) + gtest.Assert(data, []byte(content_16_cfb)) + }) +} + +func TestDecryptCFB(t *testing.T) { + gtest.Case(t, func() { + decrypt, err := gaes.DecryptCFB([]byte(content_16_cfb), key_16, padding_size, iv) + gtest.Assert(err, nil) + gtest.Assert(decrypt, content) + }) +} From 19d7ad734b2fa92c95dba6ff3e7683f8bde61efc Mon Sep 17 00:00:00 2001 From: jroam Date: Tue, 18 Jun 2019 11:20:10 +0800 Subject: [PATCH 17/19] Update gqueue_unit_test.go --- g/container/gqueue/gqueue_unit_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/g/container/gqueue/gqueue_unit_test.go b/g/container/gqueue/gqueue_unit_test.go index 8b947ca75..322c63985 100644 --- a/g/container/gqueue/gqueue_unit_test.go +++ b/g/container/gqueue/gqueue_unit_test.go @@ -15,7 +15,6 @@ import ( ) func TestQueue_Len(t *testing.T) { - max := 100 for n := 10; n < max; n++ { q1 := gqueue.New(max) @@ -44,7 +43,6 @@ func TestQueue_Pop(t *testing.T) { q1.Push(4) i1 := q1.Pop() gtest.Assert(i1, 1) - } func TestQueue_Close(t *testing.T) { From 17898cc747f5b325912e96820f4cf5240b3ded23 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 18 Jun 2019 17:31:48 +0800 Subject: [PATCH 18/19] improve gmlock --- g/container/garray/garray_func.go | 1 - g/internal/mutex/mutex.go | 3 +- g/internal/rwmutex/rwmutex.go | 3 +- g/os/gmlock/gmlock.go | 38 ++++----- g/os/gmlock/gmlock_locker.go | 48 ++++++------ g/os/gmlock/gmlock_mutex.go | 124 +++++++++++++++++------------- geg/other/test.go | 26 +++---- geg/other/test2.go | 18 ++--- 8 files changed, 134 insertions(+), 127 deletions(-) diff --git a/g/container/garray/garray_func.go b/g/container/garray/garray_func.go index 429a98d11..7366269d5 100644 --- a/g/container/garray/garray_func.go +++ b/g/container/garray/garray_func.go @@ -6,7 +6,6 @@ package garray - type apiSliceInterface interface { Slice() []interface{} } diff --git a/g/internal/mutex/mutex.go b/g/internal/mutex/mutex.go index f16fed5b2..783d95dea 100644 --- a/g/internal/mutex/mutex.go +++ b/g/internal/mutex/mutex.go @@ -4,11 +4,12 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// Package mutex provides switch for sync.Mutex for concurrent safe feature. +// Package mutex provides switch of concurrent safe feature for sync.Mutex. package mutex import "sync" +// Mutex is a sync.Mutex with a switch of concurrent safe feature. type Mutex struct { sync.Mutex safe bool diff --git a/g/internal/rwmutex/rwmutex.go b/g/internal/rwmutex/rwmutex.go index 903275d30..9f071d671 100644 --- a/g/internal/rwmutex/rwmutex.go +++ b/g/internal/rwmutex/rwmutex.go @@ -4,11 +4,12 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// Package rwmutex provides switch for sync.RWMutex for concurrent safe feature. +// Package rwmutex provides switch of concurrent safe feature for sync.RWMutex. package rwmutex import "sync" +// RWMutex is a sync.RWMutex with a switch of concurrent safe feature. type RWMutex struct { sync.RWMutex safe bool diff --git a/g/os/gmlock/gmlock.go b/g/os/gmlock/gmlock.go index 18bc88fa0..a7897c5be 100644 --- a/g/os/gmlock/gmlock.go +++ b/g/os/gmlock/gmlock.go @@ -14,46 +14,46 @@ var ( locker = New() ) -// TryLock tries locking the with write lock, -// it returns true if success, or if there's a write/read lock the , +// TryLock tries locking the with writing lock, +// it returns true if success, or if there's a write/reading lock the , // it returns false. The parameter specifies the max duration it locks. func TryLock(key string, expire...time.Duration) bool { return locker.TryLock(key, expire...) } -// Lock locks the with write lock. -// If there's a write/read lock the , +// Lock locks the with writing lock. +// If there's a write/reading lock the , // it will blocks until the lock is released. // The parameter specifies the max duration it locks. func Lock(key string, expire...time.Duration) { locker.Lock(key, expire...) } -// Unlock unlocks the write lock of the . +// Unlock unlocks the writing lock of the . func Unlock(key string) { locker.Unlock(key) } -// TryRLock tries locking the with read lock. -// It returns true if success, or if there's a write lock on , it returns false. +// TryRLock tries locking the with reading lock. +// It returns true if success, or if there's a writing lock on , it returns false. func TryRLock(key string) bool { return locker.TryRLock(key) } -// RLock locks the with read lock. -// If there's a write lock on , -// it will blocks until the write lock is released. +// RLock locks the with reading lock. +// If there's a writing lock on , +// it will blocks until the writing lock is released. func RLock(key string) { locker.RLock(key) } -// RUnlock unlocks the read lock of the . +// RUnlock unlocks the reading lock of the . func RUnlock(key string) { locker.RUnlock(key) } -// TryLockFunc locks the with write lock and callback function . -// It returns true if success, or else if there's a write/read lock the , it return false. +// TryLockFunc locks the with writing lock and callback function . +// It returns true if success, or else if there's a write/reading lock the , it return false. // // It releases the lock after is executed. // @@ -62,8 +62,8 @@ func TryLockFunc(key string, f func(), expire...time.Duration) bool { return locker.TryLockFunc(key, f, expire...) } -// TryRLockFunc locks the with read lock and callback function . -// It returns true if success, or else if there's a write lock the , it returns false. +// TryRLockFunc locks the with reading lock and callback function . +// It returns true if success, or else if there's a writing lock the , it returns false. // // It releases the lock after is executed. // @@ -72,8 +72,8 @@ func TryRLockFunc(key string, f func()) bool { return locker.TryRLockFunc(key, f) } -// LockFunc locks the with write lock and callback function . -// If there's a write/read lock the , +// LockFunc locks the with writing lock and callback function . +// If there's a write/reading lock the , // it will blocks until the lock is released. // // It releases the lock after is executed. @@ -83,8 +83,8 @@ func LockFunc(key string, f func(), expire...time.Duration) { locker.LockFunc(key, f, expire...) } -// RLockFunc locks the with read lock and callback function . -// If there's a write lock the , +// RLockFunc locks the with reading lock and callback function . +// If there's a writing lock the , // it will blocks until the lock is released. // // It releases the lock after is executed. diff --git a/g/os/gmlock/gmlock_locker.go b/g/os/gmlock/gmlock_locker.go index 6eeafbff7..f09380936 100644 --- a/g/os/gmlock/gmlock_locker.go +++ b/g/os/gmlock/gmlock_locker.go @@ -25,50 +25,50 @@ func New() *Locker { } } -// TryLock tries locking the with write lock, -// it returns true if success, or if there's a write/read lock the , -// it returns false. The parameter specifies the max duration it locks. +// TryLock tries locking the with writing lock, +// it returns true if success, or it returns false if there's a writing/reading lock the . +// The parameter specifies the max duration it locks. func (l *Locker) TryLock(key string, expire...time.Duration) bool { return l.doLock(key, l.getExpire(expire...), true) } -// Lock locks the with write lock. -// If there's a write/read lock the , +// Lock locks the with writing lock. +// If there's a write/reading lock the , // it will blocks until the lock is released. // The parameter specifies the max duration it locks. func (l *Locker) Lock(key string, expire...time.Duration) { l.doLock(key, l.getExpire(expire...), false) } -// Unlock unlocks the write lock of the . +// Unlock unlocks the writing lock of the . func (l *Locker) Unlock(key string) { if v := l.m.Get(key); v != nil { v.(*Mutex).Unlock() } } -// TryRLock tries locking the with read lock. -// It returns true if success, or if there's a write lock on , it returns false. +// TryRLock tries locking the with reading lock. +// It returns true if success, or if there's a writing lock on , it returns false. func (l *Locker) TryRLock(key string) bool { return l.doRLock(key, true) } -// RLock locks the with read lock. -// If there's a write lock on , -// it will blocks until the write lock is released. +// RLock locks the with reading lock. +// If there's a writing lock on , +// it will blocks until the writing lock is released. func (l *Locker) RLock(key string) { l.doRLock(key, false) } -// RUnlock unlocks the read lock of the . +// RUnlock unlocks the reading lock of the . func (l *Locker) RUnlock(key string) { if v := l.m.Get(key); v != nil { v.(*Mutex).RUnlock() } } -// TryLockFunc locks the with write lock and callback function . -// It returns true if success, or else if there's a write/read lock the , it return false. +// TryLockFunc locks the with writing lock and callback function . +// It returns true if success, or else if there's a write/reading lock the , it return false. // // It releases the lock after is executed. // @@ -82,8 +82,8 @@ func (l *Locker) TryLockFunc(key string, f func(), expire...time.Duration) bool return false } -// TryRLockFunc locks the with read lock and callback function . -// It returns true if success, or else if there's a write lock the , it returns false. +// TryRLockFunc locks the with reading lock and callback function . +// It returns true if success, or else if there's a writing lock the , it returns false. // // It releases the lock after is executed. // @@ -97,8 +97,8 @@ func (l *Locker) TryRLockFunc(key string, f func()) bool { return false } -// LockFunc locks the with write lock and callback function . -// If there's a write/read lock the , +// LockFunc locks the with writing lock and callback function . +// If there's a write/reading lock the , // it will blocks until the lock is released. // // It releases the lock after is executed. @@ -110,8 +110,8 @@ func (l *Locker) LockFunc(key string, f func(), expire...time.Duration) { f() } -// RLockFunc locks the with read lock and callback function . -// If there's a write lock the , +// RLockFunc locks the with reading lock and callback function . +// If there's a writing lock the , // it will blocks until the lock is released. // // It releases the lock after is executed. @@ -137,8 +137,8 @@ func (l *Locker) getExpire(expire...time.Duration) time.Duration { // It returns true if success, or else returns false. // // The parameter is true, -// it returns false immediately if it fails getting the write lock. -// If is false, it blocks until it gets the write lock. +// it returns false immediately if it fails getting the writing lock. +// If is false, it blocks until it gets the writing lock. // // The parameter specifies the max duration it locks. func (l *Locker) doLock(key string, expire time.Duration, try bool) bool { @@ -164,8 +164,8 @@ func (l *Locker) doLock(key string, expire time.Duration, try bool) bool { // It returns true if success, or else returns false. // // The parameter is true, -// it returns false immediately if it fails getting the read lock. -// If is false, it blocks until it gets the read lock. +// it returns false immediately if it fails getting the reading lock. +// If is false, it blocks until it gets the reading lock. func (l *Locker) doRLock(key string, try bool) bool { mu := l.getOrNewMutex(key) ok := true diff --git a/g/os/gmlock/gmlock_mutex.go b/g/os/gmlock/gmlock_mutex.go index 6fcd261f7..bf40cc5bf 100644 --- a/g/os/gmlock/gmlock_mutex.go +++ b/g/os/gmlock/gmlock_mutex.go @@ -8,98 +8,114 @@ package gmlock import ( "github.com/gogf/gf/g/container/gtype" + "runtime" "sync" ) -// The high level Mutex. +// The high level RWMutex. // It wraps the sync.RWMutex to implements more rich features. type Mutex struct { - mu sync.RWMutex - wid *gtype.Int64 // Unique id, used for multiple safely Unlock. - number *gtype.Int // Locking number. - // 0: writing lock false; - // 1: writing lock true; - // >=2: reading lock; + mu sync.RWMutex + wid *gtype.Int64 // Unique id, used for multiple and safe logic Unlock. + locking *gtype.Bool // Locking mark for atomic operation for *Lock and Try*Lock functions. + // There must be only one locking operation at the same time for concurrent safe purpose. + state *gtype.Int32 // Locking state: + // 0: writing lock false; + // -1: writing lock true; + // >=1: reading lock; } // NewMutex creates and returns a new mutex. func NewMutex() *Mutex { return &Mutex{ - wid : gtype.NewInt64(), - number : gtype.NewInt(), + wid : gtype.NewInt64(), + state : gtype.NewInt32(), + locking : gtype.NewBool(), } } -// Lock locks mutex for writing. +// Lock locks the mutex for writing. // If the lock is already locked for reading or writing, // Lock blocks until the lock is available. func (m *Mutex) Lock() { - m.mu.Lock() - m.number.Set(1) - m.wid.Add(1) + if m.locking.Cas(false, true) { + m.mu.Lock() + // State should be changed after locks. + m.state.Set(-1) + m.wid.Add(1) + m.locking.Set(false) + } else { + runtime.Gosched() + m.Lock() + } } -// Unlock unlocks the write lock. -// It is safe to be called multiple times. +// Unlock unlocks the writing lock. +// It is safe to be called multiple times if there's any locks or not. func (m *Mutex) Unlock() { - if m.number.Cas(1, 0) { + if m.state.Cas(-1, 0) { m.mu.Unlock() } } +// TryLock tries locking the mutex for writing. +// It returns true if success, or if there's a write/reading lock on the mutex, +// it returns false. +func (m *Mutex) TryLock() bool { + if m.locking.Cas(false, true) { + m.mu.Lock() + // State should be changed after locks. + m.state.Set(-1) + m.wid.Add(1) + m.locking.Set(false) + return true + } + return false +} + // RLock locks mutex for reading. // If the mutex is already locked for writing, // It blocks until the lock is available. func (m *Mutex) RLock() { - m.mu.RLock() - m.number.Add(2) + if m.locking.Cas(false, true) { + m.mu.RLock() + // State should be changed after locks. + m.state.Add(1) + m.locking.Set(false) + } else { + runtime.Gosched() + m.RLock() + } } -// RUnlock undoes a single RLock call; -// it does not affect other simultaneous readers. -// It is a run-time error if mutex is not locked for reading -// on entry to RUnlock. -// It is safe to be called multiple times. +// RUnlock unlocks the reading lock. +// It is safe to be called multiple times if there's any locks or not. func (m *Mutex) RUnlock() { - if n := m.number.Val(); n >= 2 && n%2 == 0 { - if n := m.number.Add(-2); n >= 0 && n%2 == 0 { - m.mu.RUnlock() - } else { - m.number.Add(2) - } + if n := m.state.Val(); n >= 1 { + if m.state.Cas(n, n - 1) { + m.mu.RUnlock() + } else { + m.RUnlock() + } } } -// TryLock tries locking the mutex for writing. -// It returns true if success, or if there's a write/read lock on the mutex, -// it returns false. -func (m *Mutex) TryLock() bool { - if m.number.Cas(0, 1) { - m.mu.Lock() - m.wid.Add(1) - return true - } - return false -} - // TryRLock tries locking the mutex for reading. // It returns true if success, or if there's a writing lock on the mutex, it returns false. -// -// Note that it's not an atomic operation. -// -// TODO It should be an atomic operation. func (m *Mutex) TryRLock() bool { - // There must be no writing lock on the mutex. - if n := m.number.Val(); n%2 == 0 { - m.mu.RLock() - m.number.Add(2) - return true + if m.locking.Cas(false, true) { + if m.state.Val() >= 0 { + m.mu.RLock() + m.state.Add(1) + m.locking.Set(false) + return true + } } return false } // TryLockFunc tries locking the mutex for writing with given callback function . -// it returns true if success, or if there's a write/read lock on the mutex, +// it returns true if success, or if there's a write/reading lock on the mutex, // it returns false. // // It releases the lock after is executed. @@ -113,7 +129,7 @@ func (m *Mutex) TryLockFunc(f func()) bool { } // TryRLockFunc tries locking the mutex for reading with given callback function . -// It returns true if success, or if there's a write lock on the mutex, it returns false. +// It returns true if success, or if there's a writing lock on the mutex, it returns false. // // It releases the lock after is executed. func (m *Mutex) TryRLockFunc(f func()) bool { @@ -126,7 +142,7 @@ func (m *Mutex) TryRLockFunc(f func()) bool { } // LockFunc locks the mutex for writing with given callback function . -// If there's a write/read lock the mutex, it will blocks until the lock is released. +// If there's a write/reading lock the mutex, it will blocks until the lock is released. // // It releases the lock after is executed. func (m *Mutex) LockFunc(f func()) { @@ -136,7 +152,7 @@ func (m *Mutex) LockFunc(f func()) { } // RLockFunc locks the mutex for reading with given callback function . -// If there's a write lock the mutex, it will blocks until the lock is released. +// If there's a writing lock the mutex, it will blocks until the lock is released. // // It releases the lock after is executed. func (m *Mutex) RLockFunc(f func()) { diff --git a/geg/other/test.go b/geg/other/test.go index 6ef91fe4c..6e2190974 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,6 +2,7 @@ package main import ( "github.com/gogf/gf/g/container/garray" + "github.com/gogf/gf/g/os/glog" "github.com/gogf/gf/g/os/gmlock" "github.com/gogf/gf/g/test/gtest" "time" @@ -13,22 +14,19 @@ func main() { go func() { mu.LockFunc(func() { array.Append(1) - time.Sleep(100 * time.Millisecond) + time.Sleep(10000 * time.Millisecond) }) }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.LockFunc(func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.LockFunc(func() { - array.Append(1) - }) - }() - + time.Sleep(10*time.Millisecond) + for i := 0; i < 10000; i++ { + go func(i int) { + time.Sleep(50 * time.Millisecond) + mu.LockFunc(func() { + glog.Print(i) + array.Append(1) + }) + }(i) + } go func() { time.Sleep(60 * time.Millisecond) mu.Unlock() diff --git a/geg/other/test2.go b/geg/other/test2.go index 4508700a1..3b6ef239b 100644 --- a/geg/other/test2.go +++ b/geg/other/test2.go @@ -1,20 +1,12 @@ package main import ( - "github.com/gogf/gf/g" - "github.com/gogf/gf/g/net/ghttp" + "fmt" + "sync" ) func main() { - s := g.Server() - s.BindHookHandler("/*any", ghttp.HOOK_BEFORE_SERVE, func(r *ghttp.Request) { - r.Response.SetAllowCrossDomainRequest("*", "PUT,GET,POST,DELETE,OPTIONS") - r.Response.Header().Set("Access-Control-Allow-Credentials", "true") - r.Response.Header().Set("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, token") - }) - s.Group("/v1").COMMON("*", func(r *ghttp.Request) { - r.Response.WriteJson(g.Map{"name": "john"}) - }) - s.SetPort(6789) - s.Run() + m := sync.RWMutex{} + m.Lock() + fmt.Println(m) } From a7dcc2c9c6fbacc50dcef95ce27f6e969fa3ca6d Mon Sep 17 00:00:00 2001 From: john Date: Tue, 18 Jun 2019 17:39:28 +0800 Subject: [PATCH 19/19] improve gmlock --- g/os/gmlock/gmlock_mutex.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/g/os/gmlock/gmlock_mutex.go b/g/os/gmlock/gmlock_mutex.go index bf40cc5bf..6c345508f 100644 --- a/g/os/gmlock/gmlock_mutex.go +++ b/g/os/gmlock/gmlock_mutex.go @@ -114,6 +114,21 @@ func (m *Mutex) TryRLock() bool { return false } +// IsLocked checks whether the mutex is locked by writing or reading lock. +func (m *Mutex) IsLocked() bool { + return m.state.Val() != 0 +} + +// IsRLocked checks whether the mutex is locked by writing lock. +func (m *Mutex) IsWLocked() bool { + return m.state.Val() < 0 +} + +// IsRLocked checks whether the mutex is locked by reading lock. +func (m *Mutex) IsRLocked() bool { + return m.state.Val() > 0 +} + // TryLockFunc tries locking the mutex for writing with given callback function . // it returns true if success, or if there's a write/reading lock on the mutex, // it returns false.