Skip to content

Commit 0b781ff

Browse files
committed
add IsLocaleMoreSpecificThan and IsLocaleBetterThan
1 parent 6626118 commit 0b781ff

File tree

2 files changed

+131
-88
lines changed

2 files changed

+131
-88
lines changed

table.go

Lines changed: 88 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -399,12 +399,11 @@ func readTableTypeSpec(sr *io.SectionReader) ([]uint32, error) {
399399
}
400400

401401
func (c *ResTableConfig) IsMoreSpecificThan(o *ResTableConfig) bool {
402-
// non-nill ResTableConfig is always more specific than nil ResTableConfig
403-
if c != nil && o == nil {
404-
return true
402+
// nil ResTableConfig is never more specific than any ResTableConfig
403+
if c == nil {
404+
return false
405405
}
406-
407-
if c == o {
406+
if o == nil {
408407
return false
409408
}
410409

@@ -427,21 +426,10 @@ func (c *ResTableConfig) IsMoreSpecificThan(o *ResTableConfig) bool {
427426
}
428427

429428
// locale
430-
if c.Language[0] != o.Language[0] {
431-
if c.Language[0] == 0 {
432-
return false
433-
}
434-
if o.Language[0] == 0 {
435-
return true
436-
}
437-
}
438-
if c.Country[0] != o.Country[0] {
439-
if c.Country[0] == 0 {
440-
return false
441-
}
442-
if o.Country[0] == 0 {
443-
return true
444-
}
429+
if diff := c.IsLocaleMoreSpecificThan(o); diff < 0 {
430+
return false
431+
} else if diff > 0 {
432+
return true
445433
}
446434

447435
// screen layout
@@ -639,12 +627,12 @@ func (c *ResTableConfig) IsBetterThan(o *ResTableConfig, r *ResTableConfig) bool
639627
return c.IsMoreSpecificThan(o)
640628
}
641629

642-
if c != nil {
643-
if o == nil || c == o {
644-
return false
645-
}
646-
} else {
647-
return o != nil
630+
// nil ResTableConfig is never better than any ResTableConfig
631+
if c == nil {
632+
return false
633+
}
634+
if o == nil {
635+
return false
648636
}
649637

650638
// imsi
@@ -658,13 +646,8 @@ func (c *ResTableConfig) IsBetterThan(o *ResTableConfig, r *ResTableConfig) bool
658646
}
659647

660648
// locale
661-
if c.Language[0] != 0 || c.Country[0] != 0 || o.Language[0] != 0 || o.Country[0] != 0 {
662-
if c.Language[0] != o.Language[0] && r.Language[0] != 0 {
663-
return c.Language[0] != 0
664-
}
665-
if c.Country[0] != o.Country[0] && r.Country[0] != 0 {
666-
return c.Country[0] != 0
667-
}
649+
if c.IsLocaleBetterThan(o, r) {
650+
return true
668651
}
669652

670653
// screen layout
@@ -771,9 +754,8 @@ func (c *ResTableConfig) IsBetterThan(o *ResTableConfig, r *ResTableConfig) bool
771754
}
772755
if (2*l-reqValue)*h > reqValue*reqValue {
773756
return !blmBigger
774-
} else {
775-
return blmBigger
776757
}
758+
return blmBigger
777759
}
778760
if c.Touchscreen != o.Touchscreen && r.Touchscreen != 0 {
779761
return c.Touchscreen != 0
@@ -845,6 +827,64 @@ func (c *ResTableConfig) IsBetterThan(o *ResTableConfig, r *ResTableConfig) bool
845827
return false
846828
}
847829

830+
func (c *ResTableConfig) IsLocaleMoreSpecificThan(o *ResTableConfig) int {
831+
if (c.Language != [2]uint8{} || c.Country != [2]uint8{}) || (o.Language != [2]uint8{} || o.Country != [2]uint8{}) {
832+
if c.Language != o.Language {
833+
if c.Language == [2]uint8{} {
834+
return -1
835+
}
836+
if o.Language == [2]uint8{} {
837+
return 1
838+
}
839+
}
840+
841+
if c.Country != o.Country {
842+
if c.Country == [2]uint8{} {
843+
return -1
844+
}
845+
if o.Country == [2]uint8{} {
846+
return 1
847+
}
848+
}
849+
}
850+
return 0
851+
}
852+
853+
func (c *ResTableConfig) IsLocaleBetterThan(o *ResTableConfig, r *ResTableConfig) bool {
854+
if r.Language == [2]uint8{} && r.Country == [2]uint8{} {
855+
// The request doesn't have a locale, so no resource is better
856+
// than the other.
857+
return false
858+
}
859+
860+
if c.Language == [2]uint8{} && c.Country == [2]uint8{} && o.Language == [2]uint8{} && o.Country == [2]uint8{} {
861+
// The locales parts of both resources are empty, so no one is better
862+
// than the other.
863+
return false
864+
}
865+
866+
if c.Language != o.Language {
867+
// The languages of the two resources are not the same.
868+
869+
// the US English resource have traditionally lived for most apps.
870+
if r.Language == [2]uint8{'e', 'n'} {
871+
if r.Country == [2]uint8{'U', 'S'} {
872+
if c.Language != [2]uint8{} {
873+
return c.Country == [2]uint8{} || c.Country == [2]uint8{'U', 'S'}
874+
}
875+
return !(c.Country == [2]uint8{} || c.Country == [2]uint8{'U', 'S'})
876+
}
877+
}
878+
return c.Language != [2]uint8{}
879+
}
880+
881+
if c.Country != o.Country {
882+
return c.Country != [2]uint8{}
883+
}
884+
885+
return false
886+
}
887+
848888
func (c *ResTableConfig) Match(settings *ResTableConfig) bool {
849889
// nil ResTableConfig always matches.
850890
if settings == nil {
@@ -874,13 +914,19 @@ func (c *ResTableConfig) Match(settings *ResTableConfig) bool {
874914
}
875915

876916
// match locale
877-
if settings.Language[0] != 0 && c.Language[0] != 0 &&
878-
!(settings.Language[0] == c.Language[0] && settings.Language[1] == c.Language[1]) {
879-
return false
880-
}
881-
if settings.Country[0] != 0 && c.Country[0] != 0 &&
882-
!(settings.Country[0] == c.Country[0] && settings.Country[1] == c.Country[1]) {
883-
return false
917+
if c.Language != [2]uint8{0, 0} {
918+
// Don't consider country and variants when deciding matches.
919+
// If two configs differ only in their country and variant,
920+
// they can be weeded out in the isMoreSpecificThan test.
921+
if c.Language != settings.Language {
922+
return false
923+
}
924+
925+
if c.Country != [2]uint8{0, 0} {
926+
if c.Country != settings.Country {
927+
return false
928+
}
929+
}
884930
}
885931

886932
// screen layout

table_test.go

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -45,61 +45,41 @@ func TestFindPackage(t *testing.T) {
4545
}
4646
}
4747

48-
func TestFindType(t *testing.T) {
48+
func TestGetResourceNil(t *testing.T) {
4949
tableFile := loadTestData()
50-
p := tableFile.findPackage(0x7F)
51-
id := 0x04
52-
config := &ResTableConfig{}
53-
tableType := p.findType(id, config)
54-
if int(tableType.Header.Id) != id {
55-
t.Errorf("got %v want %v", tableType.Header.Id, id)
56-
}
57-
locale := tableType.Header.Config.Locale()
58-
if locale != "" {
59-
t.Errorf("got %v want \"\"", locale)
50+
val, _ := tableFile.GetResource(ResId(0x7f040000), nil)
51+
if val != "FireworksMeasure" {
52+
t.Errorf(`got %v want "花火距離計算"`, val)
6053
}
6154
}
6255

63-
func TestFindTypeJa(t *testing.T) {
56+
func TestGetResourceDefault(t *testing.T) {
6457
tableFile := loadTestData()
65-
p := tableFile.findPackage(0x7F)
66-
id := 0x04
67-
config := &ResTableConfig{}
68-
config.Language[0] = uint8('j')
69-
config.Language[1] = uint8('a')
70-
tableType := p.findType(id, config)
71-
if int(tableType.Header.Id) != id {
72-
t.Errorf("got %v want %v", tableType.Header.Id, id)
73-
}
74-
locale := tableType.Header.Config.Locale()
75-
if locale != "ja" {
76-
t.Errorf("got %v want ja", locale)
58+
val, _ := tableFile.GetResource(ResId(0x7f040000), &ResTableConfig{})
59+
if val != "FireworksMeasure" {
60+
t.Errorf(`got %v want "FireworksMeasure"`, val)
7761
}
7862
}
7963

80-
func TestFindTypeEn(t *testing.T) {
64+
func TestGetResourceJA(t *testing.T) {
8165
tableFile := loadTestData()
82-
p := tableFile.findPackage(0x7F)
83-
id := 0x04
84-
config := &ResTableConfig{}
85-
config.Language[0] = uint8('e')
86-
config.Language[1] = uint8('n')
87-
tableType := p.findType(id, config)
88-
if int(tableType.Header.Id) != id {
89-
t.Errorf("got %v want %v", tableType.Header.Id, id)
66+
config := &ResTableConfig{
67+
Language: [2]uint8{'j', 'a'},
9068
}
91-
locale := tableType.Header.Config.Locale()
92-
if locale != "" {
93-
t.Errorf("got %v want \"\"", locale)
69+
val, _ := tableFile.GetResource(ResId(0x7f040000), config)
70+
if val != "花火距離計算" {
71+
t.Errorf(`got %v want "花火距離計算"`, val)
9472
}
9573
}
9674

97-
func TestGetResource(t *testing.T) {
75+
func TestGetResourceEN(t *testing.T) {
9876
tableFile := loadTestData()
99-
config := &ResTableConfig{}
77+
config := &ResTableConfig{
78+
Language: [2]uint8{'e', 'n'},
79+
}
10080
val, _ := tableFile.GetResource(ResId(0x7f040000), config)
10181
if val != "FireworksMeasure" {
102-
t.Errorf("got %v want \"\"", val)
82+
t.Errorf(`got %v want "FireworksMeasure"`, val)
10383
}
10484
}
10585

@@ -108,6 +88,21 @@ var isMoreSpecificThanTests = []struct {
10888
other *ResTableConfig
10989
expected bool
11090
}{
91+
{
92+
me: nil,
93+
other: nil,
94+
expected: false,
95+
},
96+
{
97+
me: nil,
98+
other: &ResTableConfig{},
99+
expected: false,
100+
},
101+
{
102+
me: &ResTableConfig{},
103+
other: nil,
104+
expected: false,
105+
},
111106
{
112107
me: &ResTableConfig{},
113108
other: &ResTableConfig{},
@@ -124,7 +119,9 @@ var isMoreSpecificThanTests = []struct {
124119
expected: true,
125120
},
126121
{
127-
me: &ResTableConfig{Language: [2]byte{'j', 'a'}},
122+
me: &ResTableConfig{
123+
Language: [2]uint8{'j', 'a'},
124+
},
128125
other: &ResTableConfig{},
129126
expected: true,
130127
},
@@ -230,16 +227,16 @@ func TestIsMoreSpecificThan(t *testing.T) {
230227
actual := tt.me.IsMoreSpecificThan(tt.other)
231228
if actual != tt.expected {
232229
if tt.expected {
233-
t.Errorf("%v is more specific than %v, but get false", tt.me, tt.other)
230+
t.Errorf("%+v is more specific than %+v, but get false", tt.me, tt.other)
234231
} else {
235-
t.Errorf("%v is not more specific than %v, but get true", tt.me, tt.other)
232+
t.Errorf("%+v is not more specific than %+v, but get true", tt.me, tt.other)
236233
}
237234
}
238235

239236
if tt.expected {
240237
// If 'me' is more specific than 'other', 'other' is not more specific than 'me'
241238
if tt.other.IsMoreSpecificThan(tt.me) {
242-
t.Errorf("%v is not more specific than %v, but get true", tt.other, tt.me)
239+
t.Errorf("%+v is not more specific than %+v, but get true", tt.other, tt.me)
243240
}
244241
}
245242
}
@@ -447,16 +444,16 @@ func TestIsBetterThan(t *testing.T) {
447444
actual := tt.me.IsBetterThan(tt.other, tt.require)
448445
if actual != tt.expected {
449446
if tt.expected {
450-
t.Errorf("%v is better than %v, but get false", tt.me, tt.other)
447+
t.Errorf("%+v is better than %+v, but get false (%+v)", tt.me, tt.other, tt.require)
451448
} else {
452-
t.Errorf("%v is not better than %v, but get true", tt.me, tt.other)
449+
t.Errorf("%+v is not better than %+v, but get true (%+v)", tt.me, tt.other, tt.require)
453450
}
454451
}
455452

456453
if tt.expected {
457454
// If 'me' is better than 'other', 'other' is not better than 'me'
458455
if tt.other.IsBetterThan(tt.me, tt.require) {
459-
t.Errorf("%v is not better than %v, but get true", tt.other, tt.me)
456+
t.Errorf("%v is not better than %+v, but get true (%+v)", tt.other, tt.me, tt.require)
460457
}
461458
}
462459
}

0 commit comments

Comments
 (0)