func (vi *Info) readNode(parent interface{}, data []byte) (int, error) {
	n, pos, err := readNodeHeader(data)
	if err != nil {
		return 0, err
	}
	if n.Length < sizeOfNodeHeader || int(n.Length) > len(data) {
		return 0, errors.New(errInvalidLength)
	}
	data = data[:n.Length]

	key, err := readString(data, &pos)
	if err != nil {
		return 0, err
	}

	if n.ValueLength > 0 && align(pos)+int(n.ValueLength) > len(data) {
		return 0, io.ErrUnexpectedEOF
	}

	switch true {
	case parent == nil && key == vsVersionInfo:
		if n.ValueLength >= sizeOfFixedFileInfo {
			err := vi.readFixedStruct(data[align(pos):])
			if err != nil {
				return 0, err
			}
		}
		pos += int(n.ValueLength)
		err := vi.readChildren(key, data, &pos)
		if err != nil {
			return 0, err
		}

	case parent == vsVersionInfo && key == varFileInfo:
		// skip these nodes
		break

	case parent == vsVersionInfo && key == stringFileInfo:
		err := vi.readChildren(key, data, &pos)
		if err != nil {
			return 0, err
		}

	case parent == stringFileInfo:
		var langID, codePage uint16
		_, err := fmt.Sscanf(key, "%04x%04x", &langID, &codePage)
		if err != nil {
			return 0, errors.New(errInvalidLangID)
		}
		if codePage != codePageUTF16LE {
			return 0, errors.New(errUnhandledCodePage)
		}
		err = vi.readChildren(langID, data, &pos)
		if err != nil {
			return 0, err
		}

	default:
		// Under a language ID, this is a key/value pair
		if id, ok := parent.(uint16); ok {
			pos = align(pos)
			value, err := readStringWithLength(data, &pos, int(n.ValueLength))
			if err != nil {
				return 0, err
			}
			vi.Set(id, key, value)
		}
	}

	return len(data), nil
}
// Returns the number of bytes read
Returns the number of bytes read
// Returns the number of bytes read
func (vi *Info) readNode(parent interface{}, data []byte) (int, error) {
	n, pos, err := readNodeHeader(data)
	if err != nil {
		return 0, err
	}
	if n.Length < sizeOfNodeHeader || int(n.Length) > len(data) {
		return 0, errors.New(errInvalidLength)
	}
	data = data[:n.Length]
	key, err := readString(data, &pos)
	if err != nil {
		return 0, err
	}
	if n.ValueLength > 0 && align(pos)+int(n.ValueLength) > len(data) {
		return 0, io.ErrUnexpectedEOF
	}
	switch true {
	case parent == nil && key == vsVersionInfo:
		if n.ValueLength >= sizeOfFixedFileInfo {
			err := vi.readFixedStruct(data[align(pos):])
			if err != nil {
				return 0, err
			}
		}
		pos += int(n.ValueLength)
		err := vi.readChildren(key, data, &pos)
		if err != nil {
			return 0, err
		}
	case parent == vsVersionInfo && key == varFileInfo:
		break
	case parent == vsVersionInfo && key == stringFileInfo:
		err := vi.readChildren(key, data, &pos)
		if err != nil {
			return 0, err
		}
	case parent == stringFileInfo:
		var langID, codePage uint16
		_, err := fmt.Sscanf(key, "%04x%04x", &langID, &codePage)
		if err != nil {
			return 0, errors.New(errInvalidLangID)
		}
		if codePage != codePageUTF16LE {
			return 0, errors.New(errUnhandledCodePage)
		}
		err = vi.readChildren(langID, data, &pos)
		if err != nil {
			return 0, err
		}
	default:
		if id, ok := parent.(uint16); ok {
			pos = align(pos)
			value, err := readStringWithLength(data, &pos, int(n.ValueLength))
			if err != nil {
				return 0, err
			}
			vi.Set(id, key, value)
		}
	}
	return len(data), nil
}
func ( vi * Info ) readNode ( parent interface { } , data [ ] byte ) ( int , error ) { n , pos , err := readNodeHeader ( data ) if err != nil { return 0 , err } if n . Length < sizeOfNodeHeader || int ( n . Length ) > len ( data ) { return 0 , errors . New ( errInvalidLength ) } data = data [ : n . Length ] key , err := readString ( data , & pos ) if err != nil { return 0 , err } if n . ValueLength > 0 && align ( pos ) + int ( n . ValueLength ) > len ( data ) { return 0 , io . ErrUnexpectedEOF } switch true { case parent == nil && key == vsVersionInfo : if n . ValueLength >= sizeOfFixedFileInfo { err := vi . readFixedStruct ( data [ align ( pos ) : ] ) if err != nil { return 0 , err } } pos += int ( n . ValueLength ) err := vi . readChildren ( key , data , & pos ) if err != nil { return 0 , err } case parent == vsVersionInfo && key == varFileInfo : break case parent == vsVersionInfo && key == stringFileInfo : err := vi . readChildren ( key , data , & pos ) if err != nil { return 0 , err } case parent == stringFileInfo : var langID , codePage uint16 _ , err := fmt . Sscanf ( key , " " , & langID , & codePage ) if err != nil { return 0 , errors . New ( errInvalidLangID ) } if codePage != codePageUTF16LE { return 0 , errors . New ( errUnhandledCodePage ) } err = vi . readChildren ( langID , data , & pos ) if err != nil { return 0 , err } default : if id , ok := parent . ( uint16 ) ; ok { pos = align ( pos ) value , err := readStringWithLength ( data , & pos , int ( n . ValueLength ) ) if err != nil { return 0 , err } vi . Set ( id , key , value ) } } return len ( data ) , nil }
Returns the number of bytes read
Returns the number of bytes read
// skip these nodes // Under a language ID, this is a key/value pair