github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/encoding/kmgYaml/yaml_emitter_write.go (about)

     1  package kmgYaml
     2  
     3  // Write the BOM character.
     4  func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
     5  	if !flush(emitter) {
     6  		return false
     7  	}
     8  	pos := emitter.buffer_pos
     9  	emitter.buffer[pos+0] = '\xEF'
    10  	emitter.buffer[pos+1] = '\xBB'
    11  	emitter.buffer[pos+2] = '\xBF'
    12  	emitter.buffer_pos += 3
    13  	return true
    14  }
    15  
    16  func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
    17  	indent := emitter.indent
    18  	if indent < 0 {
    19  		indent = 0
    20  	}
    21  	if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
    22  		if !put_break(emitter) {
    23  			return false
    24  		}
    25  	}
    26  	for emitter.column < indent {
    27  		if !put(emitter, ' ') {
    28  			return false
    29  		}
    30  	}
    31  	emitter.whitespace = true
    32  	emitter.indention = true
    33  	return true
    34  }
    35  
    36  func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
    37  	if need_whitespace && !emitter.whitespace {
    38  		if !put(emitter, ' ') {
    39  			return false
    40  		}
    41  	}
    42  	if !write_all(emitter, indicator) {
    43  		return false
    44  	}
    45  	emitter.whitespace = is_whitespace
    46  	emitter.indention = (emitter.indention && is_indention)
    47  	emitter.open_ended = false
    48  	return true
    49  }
    50  
    51  func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
    52  	if !write_all(emitter, value) {
    53  		return false
    54  	}
    55  	emitter.whitespace = false
    56  	emitter.indention = false
    57  	return true
    58  }
    59  
    60  func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
    61  	if !emitter.whitespace {
    62  		if !put(emitter, ' ') {
    63  			return false
    64  		}
    65  	}
    66  	if !write_all(emitter, value) {
    67  		return false
    68  	}
    69  	emitter.whitespace = false
    70  	emitter.indention = false
    71  	return true
    72  }
    73  
    74  func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
    75  	if need_whitespace && !emitter.whitespace {
    76  		if !put(emitter, ' ') {
    77  			return false
    78  		}
    79  	}
    80  	for i := 0; i < len(value); {
    81  		var must_write bool
    82  		switch value[i] {
    83  		case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
    84  			must_write = true
    85  		default:
    86  			must_write = is_alpha(value, i)
    87  		}
    88  		if must_write {
    89  			if !write(emitter, value, &i) {
    90  				return false
    91  			}
    92  		} else {
    93  			w := width(value[i])
    94  			for k := 0; k < w; k++ {
    95  				octet := value[i]
    96  				i++
    97  
    98  				c := octet >> 4
    99  				if c < 10 {
   100  					c += '0'
   101  				} else {
   102  					c += 'A' - 10
   103  				}
   104  				if !put(emitter, c) {
   105  					return false
   106  				}
   107  
   108  				c = octet & 0x0f
   109  				if c < 10 {
   110  					c += '0'
   111  				} else {
   112  					c += 'A' - 10
   113  				}
   114  				if !put(emitter, c) {
   115  					return false
   116  				}
   117  			}
   118  		}
   119  	}
   120  	emitter.whitespace = false
   121  	emitter.indention = false
   122  	return true
   123  }
   124  
   125  func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
   126  	/*
   127  		if bytes.IndexByte(value,[]byte(':'))!=-1{
   128  			return yaml_emitter_analyze_scalar()
   129  		}
   130  	*/
   131  	if !emitter.whitespace {
   132  		if !put(emitter, ' ') {
   133  			return false
   134  		}
   135  	}
   136  	spaces := false
   137  	breaks := false
   138  	for i := 0; i < len(value); {
   139  		if is_space(value, i) {
   140  			if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
   141  				if !yaml_emitter_write_indent(emitter) {
   142  					return false
   143  				}
   144  				i += width(value[i])
   145  			} else {
   146  				if !write(emitter, value, &i) {
   147  					return false
   148  				}
   149  			}
   150  			spaces = true
   151  		} else if is_break(value, i) {
   152  			if !breaks && value[i] == '\n' {
   153  				if !put_break(emitter) {
   154  					return false
   155  				}
   156  			}
   157  			if !write_break(emitter, value, &i) {
   158  				return false
   159  			}
   160  			emitter.indention = true
   161  			breaks = true
   162  		} else {
   163  			if breaks {
   164  				if !yaml_emitter_write_indent(emitter) {
   165  					return false
   166  				}
   167  			}
   168  			if !write(emitter, value, &i) {
   169  				return false
   170  			}
   171  			emitter.indention = false
   172  			spaces = false
   173  			breaks = false
   174  		}
   175  	}
   176  
   177  	emitter.whitespace = false
   178  	emitter.indention = false
   179  	if emitter.root_context {
   180  		emitter.open_ended = true
   181  	}
   182  
   183  	return true
   184  }
   185  
   186  func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
   187  
   188  	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
   189  		return false
   190  	}
   191  
   192  	spaces := false
   193  	breaks := false
   194  	for i := 0; i < len(value); {
   195  		if is_space(value, i) {
   196  			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
   197  				if !yaml_emitter_write_indent(emitter) {
   198  					return false
   199  				}
   200  				i += width(value[i])
   201  			} else {
   202  				if !write(emitter, value, &i) {
   203  					return false
   204  				}
   205  			}
   206  			spaces = true
   207  		} else if is_break(value, i) {
   208  			if !breaks && value[i] == '\n' {
   209  				if !put_break(emitter) {
   210  					return false
   211  				}
   212  			}
   213  			if !write_break(emitter, value, &i) {
   214  				return false
   215  			}
   216  			emitter.indention = true
   217  			breaks = true
   218  		} else {
   219  			if breaks {
   220  				if !yaml_emitter_write_indent(emitter) {
   221  					return false
   222  				}
   223  			}
   224  			if value[i] == '\'' {
   225  				if !put(emitter, '\'') {
   226  					return false
   227  				}
   228  			}
   229  			if !write(emitter, value, &i) {
   230  				return false
   231  			}
   232  			emitter.indention = false
   233  			spaces = false
   234  			breaks = false
   235  		}
   236  	}
   237  	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
   238  		return false
   239  	}
   240  	emitter.whitespace = false
   241  	emitter.indention = false
   242  	return true
   243  }
   244  
   245  func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
   246  	spaces := false
   247  	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
   248  		return false
   249  	}
   250  
   251  	for i := 0; i < len(value); {
   252  		if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
   253  			is_bom(value, i) || is_break(value, i) ||
   254  			value[i] == '"' || value[i] == '\\' {
   255  
   256  			octet := value[i]
   257  
   258  			var w int
   259  			var v rune
   260  			switch {
   261  			case octet&0x80 == 0x00:
   262  				w, v = 1, rune(octet&0x7F)
   263  			case octet&0xE0 == 0xC0:
   264  				w, v = 2, rune(octet&0x1F)
   265  			case octet&0xF0 == 0xE0:
   266  				w, v = 3, rune(octet&0x0F)
   267  			case octet&0xF8 == 0xF0:
   268  				w, v = 4, rune(octet&0x07)
   269  			}
   270  			for k := 1; k < w; k++ {
   271  				octet = value[i+k]
   272  				v = (v << 6) + (rune(octet) & 0x3F)
   273  			}
   274  			i += w
   275  
   276  			if !put(emitter, '\\') {
   277  				return false
   278  			}
   279  
   280  			var ok bool
   281  			switch v {
   282  			case 0x00:
   283  				ok = put(emitter, '0')
   284  			case 0x07:
   285  				ok = put(emitter, 'a')
   286  			case 0x08:
   287  				ok = put(emitter, 'b')
   288  			case 0x09:
   289  				ok = put(emitter, 't')
   290  			case 0x0A:
   291  				ok = put(emitter, 'n')
   292  			case 0x0b:
   293  				ok = put(emitter, 'v')
   294  			case 0x0c:
   295  				ok = put(emitter, 'f')
   296  			case 0x0d:
   297  				ok = put(emitter, 'r')
   298  			case 0x1b:
   299  				ok = put(emitter, 'e')
   300  			case 0x22:
   301  				ok = put(emitter, '"')
   302  			case 0x5c:
   303  				ok = put(emitter, '\\')
   304  			case 0x85:
   305  				ok = put(emitter, 'N')
   306  			case 0xA0:
   307  				ok = put(emitter, '_')
   308  			case 0x2028:
   309  				ok = put(emitter, 'L')
   310  			case 0x2029:
   311  				ok = put(emitter, 'P')
   312  			default:
   313  				if v <= 0xFF {
   314  					ok = put(emitter, 'x')
   315  					w = 2
   316  				} else if v <= 0xFFFF {
   317  					ok = put(emitter, 'u')
   318  					w = 4
   319  				} else {
   320  					ok = put(emitter, 'U')
   321  					w = 8
   322  				}
   323  				for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
   324  					digit := byte((v >> uint(k)) & 0x0F)
   325  					if digit < 10 {
   326  						ok = put(emitter, digit+'0')
   327  					} else {
   328  						ok = put(emitter, digit+'A'-10)
   329  					}
   330  				}
   331  			}
   332  			if !ok {
   333  				return false
   334  			}
   335  			spaces = false
   336  		} else if is_space(value, i) {
   337  			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
   338  				if !yaml_emitter_write_indent(emitter) {
   339  					return false
   340  				}
   341  				if is_space(value, i+1) {
   342  					if !put(emitter, '\\') {
   343  						return false
   344  					}
   345  				}
   346  				i += width(value[i])
   347  			} else if !write(emitter, value, &i) {
   348  				return false
   349  			}
   350  			spaces = true
   351  		} else {
   352  			if !write(emitter, value, &i) {
   353  				return false
   354  			}
   355  			spaces = false
   356  		}
   357  	}
   358  	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
   359  		return false
   360  	}
   361  	emitter.whitespace = false
   362  	emitter.indention = false
   363  	return true
   364  }
   365  
   366  func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
   367  	if is_space(value, 0) || is_break(value, 0) {
   368  		indent_hint := []byte{'0' + byte(emitter.best_indent)}
   369  		if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
   370  			return false
   371  		}
   372  	}
   373  
   374  	emitter.open_ended = false
   375  
   376  	var chomp_hint [1]byte
   377  	if len(value) == 0 {
   378  		chomp_hint[0] = '-'
   379  	} else {
   380  		i := len(value) - 1
   381  		for value[i]&0xC0 == 0x80 {
   382  			i--
   383  		}
   384  		if !is_break(value, i) {
   385  			chomp_hint[0] = '-'
   386  		} else if i == 0 {
   387  			chomp_hint[0] = '+'
   388  			emitter.open_ended = true
   389  		} else {
   390  			i--
   391  			for value[i]&0xC0 == 0x80 {
   392  				i--
   393  			}
   394  			if is_break(value, i) {
   395  				chomp_hint[0] = '+'
   396  				emitter.open_ended = true
   397  			}
   398  		}
   399  	}
   400  	if chomp_hint[0] != 0 {
   401  		if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
   402  			return false
   403  		}
   404  	}
   405  	return true
   406  }
   407  
   408  func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
   409  	if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
   410  		return false
   411  	}
   412  	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
   413  		return false
   414  	}
   415  	if !put_break(emitter) {
   416  		return false
   417  	}
   418  	emitter.indention = true
   419  	emitter.whitespace = true
   420  	breaks := true
   421  	for i := 0; i < len(value); {
   422  		if is_break(value, i) {
   423  			if !write_break(emitter, value, &i) {
   424  				return false
   425  			}
   426  			emitter.indention = true
   427  			breaks = true
   428  		} else {
   429  			if breaks {
   430  				if !yaml_emitter_write_indent(emitter) {
   431  					return false
   432  				}
   433  			}
   434  			if !write(emitter, value, &i) {
   435  				return false
   436  			}
   437  			emitter.indention = false
   438  			breaks = false
   439  		}
   440  	}
   441  
   442  	return true
   443  }
   444  
   445  func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
   446  	if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
   447  		return false
   448  	}
   449  	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
   450  		return false
   451  	}
   452  
   453  	if !put_break(emitter) {
   454  		return false
   455  	}
   456  	emitter.indention = true
   457  	emitter.whitespace = true
   458  
   459  	breaks := true
   460  	leading_spaces := true
   461  	for i := 0; i < len(value); {
   462  		if is_break(value, i) {
   463  			if !breaks && !leading_spaces && value[i] == '\n' {
   464  				k := 0
   465  				for is_break(value, k) {
   466  					k += width(value[k])
   467  				}
   468  				if !is_blankz(value, k) {
   469  					if !put_break(emitter) {
   470  						return false
   471  					}
   472  				}
   473  			}
   474  			if !write_break(emitter, value, &i) {
   475  				return false
   476  			}
   477  			emitter.indention = true
   478  			breaks = true
   479  		} else {
   480  			if breaks {
   481  				if !yaml_emitter_write_indent(emitter) {
   482  					return false
   483  				}
   484  				leading_spaces = is_blank(value, i)
   485  			}
   486  			if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
   487  				if !yaml_emitter_write_indent(emitter) {
   488  					return false
   489  				}
   490  				i += width(value[i])
   491  			} else {
   492  				if !write(emitter, value, &i) {
   493  					return false
   494  				}
   495  			}
   496  			emitter.indention = false
   497  			breaks = false
   498  		}
   499  	}
   500  	return true
   501  }