github.com/phpdave11/gofpdf@v1.4.2/compare.go (about)

     1  /*
     2   * Copyright (c) 2015 Kurt Jung (Gmail: kurt.w.jung)
     3   *
     4   * Permission to use, copy, modify, and distribute this software for any
     5   * purpose with or without fee is hereby granted, provided that the above
     6   * copyright notice and this permission notice appear in all copies.
     7   *
     8   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     9   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    10   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    11   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    12   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    13   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    14   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    15   */
    16  
    17  package gofpdf
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"sort"
    25  )
    26  
    27  type sortType struct {
    28  	length int
    29  	less   func(int, int) bool
    30  	swap   func(int, int)
    31  }
    32  
    33  func (s *sortType) Len() int {
    34  	return s.length
    35  }
    36  
    37  func (s *sortType) Less(i, j int) bool {
    38  	return s.less(i, j)
    39  }
    40  
    41  func (s *sortType) Swap(i, j int) {
    42  	s.swap(i, j)
    43  }
    44  
    45  func gensort(Len int, Less func(int, int) bool, Swap func(int, int)) {
    46  	sort.Sort(&sortType{length: Len, less: Less, swap: Swap})
    47  }
    48  
    49  func writeBytes(leadStr string, startPos int, sl []byte) {
    50  	var pos, max int
    51  	var b byte
    52  	fmt.Printf("%s %07x", leadStr, startPos)
    53  	max = len(sl)
    54  	for pos < max {
    55  		fmt.Printf(" ")
    56  		for k := 0; k < 8; k++ {
    57  			if pos < max {
    58  				fmt.Printf(" %02x", sl[pos])
    59  			} else {
    60  				fmt.Printf("   ")
    61  			}
    62  			pos++
    63  		}
    64  	}
    65  	fmt.Printf("  |")
    66  	pos = 0
    67  	for pos < max {
    68  		b = sl[pos]
    69  		if b < 32 || b >= 128 {
    70  			b = '.'
    71  		}
    72  		fmt.Printf("%c", b)
    73  		pos++
    74  	}
    75  	fmt.Printf("|\n")
    76  }
    77  
    78  func checkBytes(pos int, sl1, sl2 []byte, printDiff bool) (eq bool) {
    79  	eq = bytes.Equal(sl1, sl2)
    80  	if !eq && printDiff {
    81  		writeBytes("<", pos, sl1)
    82  		writeBytes(">", pos, sl2)
    83  	}
    84  	return
    85  }
    86  
    87  // CompareBytes compares the bytes referred to by sl1 with those referred to by
    88  // sl2. Nil is returned if the buffers are equal, otherwise an error.
    89  func CompareBytes(sl1, sl2 []byte, printDiff bool) (err error) {
    90  	var posStart, posEnd, len1, len2, length int
    91  	var diffs bool
    92  
    93  	len1 = len(sl1)
    94  	len2 = len(sl2)
    95  	length = len1
    96  	if length > len2 {
    97  		length = len2
    98  	}
    99  	for posStart < length-1 {
   100  		posEnd = posStart + 16
   101  		if posEnd > length {
   102  			posEnd = length
   103  		}
   104  		if !checkBytes(posStart, sl1[posStart:posEnd], sl2[posStart:posEnd], printDiff) {
   105  			diffs = true
   106  		}
   107  		posStart = posEnd
   108  	}
   109  	if diffs {
   110  		err = fmt.Errorf("documents are different")
   111  	}
   112  	return
   113  }
   114  
   115  // ComparePDFs reads and compares the full contents of the two specified
   116  // readers byte-for-byte. Nil is returned if the buffers are equal, otherwise
   117  // an error.
   118  func ComparePDFs(rdr1, rdr2 io.Reader, printDiff bool) (err error) {
   119  	var b1, b2 *bytes.Buffer
   120  	_, err = b1.ReadFrom(rdr1)
   121  	if err == nil {
   122  		_, err = b2.ReadFrom(rdr2)
   123  		if err == nil {
   124  			err = CompareBytes(b1.Bytes(), b2.Bytes(), printDiff)
   125  		}
   126  	}
   127  	return
   128  }
   129  
   130  // ComparePDFFiles reads and compares the full contents of the two specified
   131  // files byte-for-byte. Nil is returned if the file contents are equal, or if
   132  // the second file is missing, otherwise an error.
   133  func ComparePDFFiles(file1Str, file2Str string, printDiff bool) (err error) {
   134  	var sl1, sl2 []byte
   135  	sl1, err = ioutil.ReadFile(file1Str)
   136  	if err == nil {
   137  		sl2, err = ioutil.ReadFile(file2Str)
   138  		if err == nil {
   139  			err = CompareBytes(sl1, sl2, printDiff)
   140  		} else {
   141  			// Second file is missing; treat this as success
   142  			err = nil
   143  		}
   144  	}
   145  	return
   146  }