github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/bufio/scan.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package bufio 6 7 import ( 8 "github.com/shogo82148/std/errors" 9 "github.com/shogo82148/std/io" 10 ) 11 12 // Scannerは、改行で区切られたテキストの行のファイルなどのデータを読み取るための便利なインターフェースを提供します。Scanメソッドの連続した呼び出しにより、ファイルの「トークン」を順番にステップし、トークン間のバイトをスキップします。トークンの仕様は [SplitFunc] 型の分割関数によって定義されます。デフォルトの分割関数は、入力を行に分割し、行末の文字を取り除きます。[Scanner.Split] 関数は、ファイルを行、バイト、UTF-8エンコードされたルーン、スペースで区切られた単語にスキャンするために、このパッケージで定義されています。クライアントは代わりにカスタムの分割関数を提供することもできます。 13 // 14 // スキャンは、EOF、最初のI/Oエラー、または [Scanner.Buffer] に収まりきらないトークンで不可回復的に停止します。 15 // スキャンが停止すると、リーダーは最後のトークンを超えて任意の距離を進めている可能性があります。 16 // エラー処理や大きなトークンの制御が必要なプログラム、またはリーダーで連続的なスキャンを実行する必要があるプログラムは、 17 // 代わりに [bufio.Reader] を使用する必要があります。 18 type Scanner struct { 19 r io.Reader 20 split SplitFunc 21 maxTokenSize int 22 token []byte 23 buf []byte 24 start int 25 end int 26 err error 27 empties int 28 scanCalled bool 29 done bool 30 } 31 32 // SplitFuncは、入力をトークン化するために使用されるsplit関数のシグネチャです。 33 // 引数は、残りの未処理データの初期部分のサブストリングと、 [Reader] にもうデータがないことを報告するフラグであるatEOFです。 34 // 戻り値は、入力を進めるためのバイト数と、ユーザーに返す次のトークン(あれば)、およびエラー(あれば)です。 35 // 36 // 関数がエラーを返した場合、スキャンは停止します。この場合、入力の一部が破棄される可能性があります。 37 // エラーが [ErrFinalToken] である場合、スキャンはエラーなしで停止します。 38 // [ErrFinalToken] と一緒に非nilトークンが配信される場合、最後のトークンとなり、 39 // [ErrFinalToken] と一緒にnilトークンが配信される場合、スキャンが直ちに停止します。 40 // 41 // それ以外の場合、スキャナは入力を進めます。トークンがnilでない場合、スキャナはユーザーにそれを返します。トークンがnilの場合、スキャナはさらにデータを読み込んでスキャンを続けます。もしデータがもうない場合(つまり、atEOFがtrueの場合)、スキャナは終了します。データがまだ完全なトークンを保持していない場合、例えば改行がない場合は、 [SplitFunc] は(0、nil、nil)を返して [Scanner] にデータをスライスに読み込んで再試行するように指示できます。 42 // 43 // この関数は、空のデータスライスでは呼び出されません(ただし、atEOFがtrueの場合は除く)。ただし、atEOFがtrueの場合、データが空でなく、常に未処理のテキストを保持しているかもしれません。 44 type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error) 45 46 // Scannerが返すエラー。 47 var ( 48 ErrTooLong = errors.New("bufio.Scanner: token too long") 49 ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count") 50 ErrAdvanceTooFar = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input") 51 ErrBadReadCount = errors.New("bufio.Scanner: Read returned impossible count") 52 ) 53 54 const ( 55 // MaxScanTokenSizeは、トークンをバッファリングするために使用される最大サイズです 56 // ユーザーが [Scanner.Buffer] で明示的なバッファを提供しない限り。 57 // 実際の最大トークンサイズは、バッファに改行などを含める必要があるため、より小さくなる場合があります。 58 MaxScanTokenSize = 64 * 1024 59 ) 60 61 // NewScannerはrから読み取るための新しい [Scanner] を返します。 62 // split関数はデフォルトで [ScanLines] になります。 63 64 func NewScanner(r io.Reader) *Scanner 65 66 // Errは [Scanner] によって遭遇した最初のEOF以外のエラーを返します。 67 func (s *Scanner) Err() error 68 69 // BytesはScanの呼び出しによって生成された最新のトークンを返します。 70 // 基になる配列は、後続の [Scanner.Scan] の呼び出しによって上書きされる可能性があります。 71 // メモリ確保は行われません。 72 func (s *Scanner) Bytes() []byte 73 74 // Textは [Scanner.Scan] の呼び出しで生成された最新のトークンを、そのバイトを保持する新しく割り当てられた文字列として返します。 75 func (s *Scanner) Text() string 76 77 // ErrFinalTokenは、特別なセンチネルエラー値です。 78 // スキャンをエラーなしで停止することを示すために、Split関数によって返されることを意図しています。 79 // このエラーと一緒に配信されるトークンがnilでない場合、トークンは最後のトークンです。 80 // 81 // この値は、処理を早期に停止する必要がある場合や、最後の空のトークン(nilトークンとは異なる)を配信する必要がある場合に役立ちます。 82 // カスタムエラー値で同じ動作を実現できますが、ここで提供することで整理されたコードになります。 83 // この値の使用例については、emptyFinalTokenの例を参照してください。 84 var ErrFinalToken = errors.New("final token") 85 86 // Scanは、 [Scanner.Bytes] または [Scanner.Text] メソッドを介して利用可能な次のトークンに [Scanner] を進めます。 87 // 入力の終わりに到達するかエラーが発生すると、falseを返します。 88 // Scanがfalseを返した後、 [Scanner.Err] メソッドはスキャン中に発生したエラーを返しますが、 89 // エラーが[io.EOF]の場合、 [Scanner.Err] はnilを返します。 90 // スキャンが進まずに空のトークンを多数返す場合、スキャナーはpanicします。 91 // これは、スキャナーの一般的なエラーモードです。 92 func (s *Scanner) Scan() bool 93 94 // Bufferは、スキャン中に使用する初期バッファと、割り当て可能な最大バッファサイズを設定します。 95 // 最大トークンサイズは、maxとcap(buf)の大きい方よりも小さくなければなりません。 96 // max <= cap(buf)の場合、 [Scanner.Scan] はこのバッファのみを使用し、割り当てを行いません。 97 // 98 // デフォルトでは、[Scanner.Scan] は内部バッファを使用し、最大トークンサイズを [MaxScanTokenSize] に設定します。 99 // 100 // Bufferはスキャンの開始後に呼び出された場合、パニックを発生させます。 101 func (s *Scanner) Buffer(buf []byte, max int) 102 103 // Splitは [Scanner] の分割関数を設定します。 104 // デフォルトの分割関数は [ScanLines] です。 105 // 106 // Splitはスキャンが開始された後に呼び出された場合、パニックを引き起こします。 107 func (s *Scanner) Split(split SplitFunc) 108 109 // ScanBytesは、各バイトをトークンとして返す [Scanner] の分割関数です。 110 func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) 111 112 // ScanRunesは、 [Scanner] に対して使用される分割関数で、それぞれのUTF-8エンコードされたルーンをトークンとして返します。返されるルーンのシーケンスは、文字列としての入力を範囲ループで処理した場合と同等です。つまり、誤ったUTF-8エンコーディングはU+FFFD = "\xef\xbf\xbd"に変換されます。Scanインターフェースのため、クライアントは正しくエンコードされた置換ルーンとエンコーディングエラーを区別することが不可能です。 113 func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) 114 115 // ScanLinesは、改行マーカー以降のテキストが除かれた、 [Scanner] のスプリット関数です。 116 // 返される行は空になる場合もあります。 117 // 改行マーカーは1つのオプションのキャリッジリターンに続いて1つの必須の改行からなります。 118 // 正規表現の表記では、 `\r?\n`です。 119 // 入力の最後の非空行は改行がない場合でも返されます。 120 func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) 121 122 // ScanWordsは、スペースで区切られたテキストの [Scanner] のための分割関数です。周囲のスペースは削除され、空の文字列は返されません。スペースの定義はunicode.IsSpaceによって設定されます。 123 func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)