Skip to content

Instantly share code, notes, and snippets.

@shiimaxx
Created April 25, 2018 11:24
Show Gist options
  • Save shiimaxx/6d5c70c98cc83d6a085c93e4f573245a to your computer and use it in GitHub Desktop.
Save shiimaxx/6d5c70c98cc83d6a085c93e4f573245a to your computer and use it in GitHub Desktop.
`image.Decode()`のコードリーディング
func Decode(r io.Reader) (Image, string, error) {

os.Fileなどのio.Readerインターフェースを実装している型の変数を引数に取る。

	rr := asReader(r)

rを引数としてasReader()が実行される。


asReader()のなか

func asReader(r io.Reader) reader {
	if rr, ok := r.(reader); ok {
		return rr
	}

型アサーション。reader型にキャストできればそれを返す。 reader型の定義は↓

type reader interface {
	io.Reader
	Peek(int) ([]byte, error)
}
	return bufio.NewReader(r)

キャストできない場合はbufio.NewReader()bufio.Readerにしを返す。
bufio.Readerはメソッドにfunc (b *Reader) Peek(n int) ([]byte, error)があるので、reader型を実装していることになる。

	f := sniff(rr)
func sniff(r reader) format {
	for _, f := range formats {
		b, err := r.Peek(len(f.magic))
		if err == nil && match(f.magic, b) {
			return f
		}
	}

formatsには登録が完了しているフォーマットのリストが入っている。

r.Peek(len(f.magic))でフォーマットのマジックナンバーの長さ分のバイトを読み込む。

match(f.magic, b)でフォーマットのマジックナンバーと読み込んだバイトが一致することをチェック。
trueであればそのままfを返す。

	if f.decode == nil {
		return nil, "", ErrFormat
	}

f := sniff(rr)でフォーマットのチェックがエラーだった場合はErrFormatを返す。

	m, err := f.decode(rr)

各フォーマットのパッケージで実装されているdecodeメソッドによってデコードを実行する。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment