1//  Copyright (c) 2014 Couchbase, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// 		http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package document
16
17import (
18	"fmt"
19	"reflect"
20
21	"github.com/blevesearch/bleve/analysis"
22	"github.com/blevesearch/bleve/size"
23)
24
25var reflectStaticSizeBooleanField int
26
27func init() {
28	var f BooleanField
29	reflectStaticSizeBooleanField = int(reflect.TypeOf(f).Size())
30}
31
32const DefaultBooleanIndexingOptions = StoreField | IndexField | DocValues
33
34type BooleanField struct {
35	name              string
36	arrayPositions    []uint64
37	options           IndexingOptions
38	value             []byte
39	numPlainTextBytes uint64
40}
41
42func (b *BooleanField) Size() int {
43	return reflectStaticSizeBooleanField + size.SizeOfPtr +
44		len(b.name) +
45		len(b.arrayPositions)*size.SizeOfUint64 +
46		len(b.value)
47}
48
49func (b *BooleanField) Name() string {
50	return b.name
51}
52
53func (b *BooleanField) ArrayPositions() []uint64 {
54	return b.arrayPositions
55}
56
57func (b *BooleanField) Options() IndexingOptions {
58	return b.options
59}
60
61func (b *BooleanField) Analyze() (int, analysis.TokenFrequencies) {
62	tokens := make(analysis.TokenStream, 0)
63	tokens = append(tokens, &analysis.Token{
64		Start:    0,
65		End:      len(b.value),
66		Term:     b.value,
67		Position: 1,
68		Type:     analysis.Boolean,
69	})
70
71	fieldLength := len(tokens)
72	tokenFreqs := analysis.TokenFrequency(tokens, b.arrayPositions, b.options.IncludeTermVectors())
73	return fieldLength, tokenFreqs
74}
75
76func (b *BooleanField) Value() []byte {
77	return b.value
78}
79
80func (b *BooleanField) Boolean() (bool, error) {
81	if len(b.value) == 1 {
82		return b.value[0] == 'T', nil
83	}
84	return false, fmt.Errorf("boolean field has %d bytes", len(b.value))
85}
86
87func (b *BooleanField) GoString() string {
88	return fmt.Sprintf("&document.BooleanField{Name:%s, Options: %s, Value: %s}", b.name, b.options, b.value)
89}
90
91func (b *BooleanField) NumPlainTextBytes() uint64 {
92	return b.numPlainTextBytes
93}
94
95func NewBooleanFieldFromBytes(name string, arrayPositions []uint64, value []byte) *BooleanField {
96	return &BooleanField{
97		name:              name,
98		arrayPositions:    arrayPositions,
99		value:             value,
100		options:           DefaultNumericIndexingOptions,
101		numPlainTextBytes: uint64(len(value)),
102	}
103}
104
105func NewBooleanField(name string, arrayPositions []uint64, b bool) *BooleanField {
106	return NewBooleanFieldWithIndexingOptions(name, arrayPositions, b, DefaultNumericIndexingOptions)
107}
108
109func NewBooleanFieldWithIndexingOptions(name string, arrayPositions []uint64, b bool, options IndexingOptions) *BooleanField {
110	numPlainTextBytes := 5
111	v := []byte("F")
112	if b {
113		numPlainTextBytes = 4
114		v = []byte("T")
115	}
116	return &BooleanField{
117		name:              name,
118		arrayPositions:    arrayPositions,
119		value:             v,
120		options:           options,
121		numPlainTextBytes: uint64(numPlainTextBytes),
122	}
123}
124