github.com/containerd/nerdctl/v2@v2.0.0-beta.5.0.20240520001846-b5758f54fa28/pkg/tabutil/tabutil.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package tabutil
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  )
    23  
    24  type TabReader struct {
    25  	indexs  map[string]*headerIndex
    26  	headers []string
    27  }
    28  
    29  type headerIndex struct {
    30  	start int
    31  	end   int
    32  }
    33  
    34  func NewReader(header string) *TabReader {
    35  	headers := strings.Split(strings.TrimSpace(header), "\t")
    36  	return &TabReader{
    37  		indexs:  make(map[string]*headerIndex),
    38  		headers: headers,
    39  	}
    40  }
    41  
    42  func (r *TabReader) ParseHeader(header string) error {
    43  	if len(r.headers) == 0 {
    44  		return fmt.Errorf("no header")
    45  	}
    46  	for i := range r.headers {
    47  		start := strings.Index(header, r.headers[i])
    48  		if start == -1 {
    49  			return fmt.Errorf("header %q not matched", r.headers[i])
    50  		}
    51  		if i > 0 {
    52  			r.indexs[r.headers[i-1]].end = start
    53  		}
    54  		r.indexs[r.headers[i]] = &headerIndex{start, -1}
    55  	}
    56  	return nil
    57  }
    58  
    59  func (r *TabReader) ReadRow(row, key string) (string, bool) {
    60  	idx, ok := r.indexs[key]
    61  	if !ok {
    62  		return "", false
    63  	}
    64  	var value string
    65  	if idx.end == -1 {
    66  		value = row[idx.start:]
    67  	} else {
    68  		value = row[idx.start:idx.end]
    69  	}
    70  	return strings.TrimSpace(value), true
    71  }