generated from cloudwego/.github
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
629c729
commit e450f27
Showing
3 changed files
with
211 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2024 CloudWeGo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package apache_adaptor | ||
|
||
import "io" | ||
|
||
// byteBuffer | ||
type byteBuffer interface { | ||
// Next reads the next n bytes sequentially and returns the original buffer. | ||
Next(n int) (p []byte, err error) | ||
|
||
// ReadableLen returns the total length of readable buffer. | ||
// Return: -1 means unreadable. | ||
ReadableLen() (n int) | ||
|
||
// Malloc n bytes sequentially in the writer buffer. | ||
Malloc(n int) (buf []byte, err error) | ||
} | ||
|
||
// byteBufferWrapper is an adaptor that implement Read() by Next() and ReadableLen() and implement Write() by Malloc() | ||
type byteBufferWrapper struct { | ||
b byteBuffer | ||
} | ||
|
||
func byteBuffer2ReadWriter(n byteBuffer) io.ReadWriter { | ||
return &byteBufferWrapper{b: n} | ||
} | ||
|
||
// Read reads data from the byteBufferWrapper's internal buffer into p. | ||
func (bw byteBufferWrapper) Read(p []byte) (n int, err error) { | ||
readable := bw.b.ReadableLen() | ||
if readable == -1 { | ||
return 0, err | ||
} | ||
if readable > len(p) { | ||
readable = len(p) | ||
} | ||
data, err := bw.b.Next(readable) | ||
if err != nil { | ||
return -1, err | ||
} | ||
copy(p, data) | ||
return readable, nil | ||
} | ||
|
||
// Write writes data from the byteBufferWrapper's internal buffer into p. | ||
func (bw byteBufferWrapper) Write(p []byte) (n int, err error) { | ||
data, err := bw.b.Malloc(len(p)) | ||
if err != nil { | ||
return -1, err | ||
} | ||
copy(data, p) | ||
return len(data), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright 2024 CloudWeGo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package apache_adaptor | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
|
||
"github.com/cloudwego/gopkg/protocol/thrift" | ||
) | ||
|
||
type fastReader interface { | ||
FastRead(buf []byte) (int, error) | ||
} | ||
|
||
const OldFastWriteMethod = "FastWriteNocopy" | ||
|
||
func toFastCodec(p interface{}) (thrift.FastCodec, error) { | ||
// if struct is from kitex_gen which is generated higher than v0.10.0,just assert gopkg thrift.FastCodec | ||
if fast, ok := p.(thrift.FastCodec); ok { | ||
return fast, nil | ||
} | ||
// if struct is lower than v0.10.0,the second argument 'bw' from FastWriterNocopy is from kitex package | ||
// it's not good to import an old kitex dependency, so we have to use reflection | ||
fast, ok := p.(interface { | ||
BLength() int | ||
FastRead(buf []byte) (int, error) | ||
}) | ||
if !ok { | ||
return nil, fmt.Errorf("no BLength method for struct") | ||
} | ||
|
||
method := reflect.ValueOf(p).MethodByName(OldFastWriteMethod) | ||
|
||
if !method.IsValid() { | ||
return nil, fmt.Errorf("method not found or not exported: %s", OldFastWriteMethod) | ||
} | ||
|
||
if method.Type().NumIn() != 2 { | ||
return nil, fmt.Errorf("args num is not ok") | ||
} | ||
|
||
if method.Type().NumOut() != 1 { | ||
return nil, fmt.Errorf("resp num is not ok") | ||
} | ||
|
||
if method.Type().Out(0) != reflect.TypeOf(0) { | ||
return nil, fmt.Errorf("return type is not int") | ||
} | ||
|
||
if method.Type().In(0) != reflect.TypeOf([]byte{}) { | ||
return nil, fmt.Errorf("input type 1st is not []byte") | ||
} | ||
|
||
return &oldFastCodec{ | ||
p: fast, | ||
method: method, | ||
}, nil | ||
} | ||
|
||
type oldFastCodec struct { | ||
p interface { | ||
BLength() int | ||
FastRead(buf []byte) (int, error) | ||
} | ||
method reflect.Value | ||
} | ||
|
||
func (c *oldFastCodec) BLength() int { | ||
return c.p.BLength() | ||
} | ||
|
||
func (c *oldFastCodec) FastWriteNocopy(buf []byte, bw thrift.NocopyWriter) int { | ||
method := c.method | ||
out := method.Call([]reflect.Value{reflect.ValueOf(buf), reflect.New(method.Type().In(1)).Elem()}) | ||
return out[0].Interface().(int) | ||
} | ||
|
||
func (c *oldFastCodec) FastRead(buf []byte) (int, error) { | ||
return c.p.FastRead(buf) | ||
} |