|
2 | 2 |
|
3 | 3 | package py |
4 | 4 |
|
5 | | -varBytesType=NewType("bytes", "bytes(iterable_of_ints) -> bytes\nbytes(string, encoding[, errors]) -> bytes\nbytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\nbytes(int) -> bytes object of size given by the parameter initialized with null bytes\nbytes() -> empty bytes object\n\nConstruct an immutable array of bytes from:\n - an iterable yielding integers in range(256)\n - a text string encoded using the specified encoding\n - any object implementing the buffer API.\n - an integer") |
| 5 | +import ( |
| 6 | +"strings" |
| 7 | +) |
| 8 | + |
| 9 | +varBytesType=ObjectType.NewType("bytes", |
| 10 | +`bytes(iterable_of_ints) -> bytes |
| 11 | +bytes(string, encoding[, errors]) -> bytes |
| 12 | +bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer |
| 13 | +bytes(int) -> bytes object of size given by the parameter initialized with null bytes |
| 14 | +bytes() -> empty bytes object |
| 15 | +
|
| 16 | +Construct an immutable array of bytes from: |
| 17 | + - an iterable yielding integers in range(256) |
| 18 | + - a text string encoded using the specified encoding |
| 19 | + - any object implementing the buffer API. |
| 20 | + - an integer`, BytesNew, nil) |
6 | 21 |
|
7 | 22 | typeBytes []byte |
8 | 23 |
|
9 | 24 | // Type of this Bytes object |
10 | 25 | func (oBytes) Type() *Type{ |
11 | 26 | returnBytesType |
12 | 27 | } |
| 28 | + |
| 29 | +// BytesNew |
| 30 | +funcBytesNew(metatype*Type, argsTuple, kwargsStringDict) (resObject){ |
| 31 | +varxObject |
| 32 | +varencodingObject |
| 33 | +varerrorsObject |
| 34 | +varNewObject |
| 35 | +kwlist:= []string{"source", "encoding", "errors"} |
| 36 | + |
| 37 | +ParseTupleAndKeywords(args, kwargs, "|Oss:bytes", kwlist, &x, &encoding, &errors) |
| 38 | +ifx==nil{ |
| 39 | +ifencoding!=nil||errors!=nil{ |
| 40 | +panic(ExceptionNewf(TypeError, "encoding or errors without sequence argument")) |
| 41 | + } |
| 42 | +returnBytes{} |
| 43 | + } |
| 44 | + |
| 45 | +ifs, ok:=x.(String); ok{ |
| 46 | +// Encode via the codec registry |
| 47 | +ifencoding==nil{ |
| 48 | +panic(ExceptionNewf(TypeError, "string argument without an encoding")) |
| 49 | + } |
| 50 | +encodingStr:=strings.ToLower(string(encoding.(String))) |
| 51 | +ifencodingStr=="utf-8"||encodingStr=="utf8"{ |
| 52 | +returnBytes([]byte(s)) |
| 53 | + } |
| 54 | +// FIXME |
| 55 | +// New = PyUnicode_AsEncodedString(x, encoding, errors) |
| 56 | +// assert(PyBytes_Check(New)) |
| 57 | +// return New |
| 58 | +panic(ExceptionNewf(NotImplementedError, "String decode for %q not implemented", encodingStr)) |
| 59 | + } |
| 60 | + |
| 61 | +// We'd like to call PyObject_Bytes here, but we need to check for an |
| 62 | +// integer argument before deferring to PyBytes_FromObject, something |
| 63 | +// PyObject_Bytes doesn't do. |
| 64 | +varokbool |
| 65 | +ifI, ok:=x.(I__bytes__); ok{ |
| 66 | +New=I.M__bytes__() |
| 67 | + } elseifNew, ok=TypeCall0(x, "__bytes__"); ok{ |
| 68 | + } else{ |
| 69 | +goto no_bytes_method |
| 70 | + } |
| 71 | +if_, ok=New.(Bytes); !ok{ |
| 72 | +panic(ExceptionNewf(TypeError, "__bytes__ returned non-bytes (type %s)", New.Type().Name)) |
| 73 | + } |
| 74 | +no_bytes_method: |
| 75 | + |
| 76 | +// Is it an integer? |
| 77 | +if_, ok:=x.(Int); ok{ |
| 78 | +size:=IndexInt(x) |
| 79 | +ifsize<0{ |
| 80 | +panic(ExceptionNewf(ValueError, "negative count")) |
| 81 | + } |
| 82 | +returnmake(Bytes, size) |
| 83 | + } |
| 84 | + |
| 85 | +// If it's not unicode, there can't be encoding or errors |
| 86 | +ifencoding!=nil||errors!=nil{ |
| 87 | +panic(ExceptionNewf(TypeError, "encoding or errors without a string argument")) |
| 88 | + } |
| 89 | + |
| 90 | +returnBytesFromObject(x) |
| 91 | +} |
| 92 | + |
| 93 | +// Converts an object into bytes |
| 94 | +funcBytesFromObject(xObject) Bytes{ |
| 95 | +// Look for special cases |
| 96 | +// FIXME implement converting from any object implementing the buffer API. |
| 97 | +switchz:=x.(type){ |
| 98 | +caseBytes: |
| 99 | +// Immutable type so just return what was passed in |
| 100 | +returnz |
| 101 | +caseString: |
| 102 | +panic(ExceptionNewf(TypeError, "cannot convert unicode object to bytes")) |
| 103 | + } |
| 104 | +// Otherwise iterate through the whatever converting it into ints |
| 105 | +b:=Bytes{} |
| 106 | +Iterate(x, func(itemObject){ |
| 107 | +value:=IndexInt(item) |
| 108 | +ifvalue<0||value>=256{ |
| 109 | +panic(ExceptionNewf(ValueError, "bytes must be in range(0, 256)")) |
| 110 | + } |
| 111 | +b=append(b, byte(value)) |
| 112 | + }) |
| 113 | +returnb |
| 114 | +} |
0 commit comments