зеркало из https://github.com/golang/snappy.git
Add a snappytool command that uses the C++ library.
The pi.txt.rawsnappy file was generated by this tool, on an amd64 (little-endian) system.
This commit is contained in:
Родитель
f1ae40350d
Коммит
343d0f4579
|
@ -1,3 +1,4 @@
|
||||||
|
cmd/snappytool/snappytool
|
||||||
testdata/bench
|
testdata/bench
|
||||||
|
|
||||||
# These explicitly listed benchmark data files are for an obsolete version of
|
# These explicitly listed benchmark data files are for an obsolete version of
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
To build the snappytool binary:
|
||||||
|
g++ main.cpp /usr/lib/libsnappy.a -o snappytool
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "snappy.h"
|
||||||
|
|
||||||
|
#define N 1000000
|
||||||
|
|
||||||
|
char dst[N];
|
||||||
|
char src[N];
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
// Parse args.
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "exactly one of -d or -e must be given\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bool decode = strcmp(argv[1], "-d") == 0;
|
||||||
|
bool encode = strcmp(argv[1], "-e") == 0;
|
||||||
|
if (decode == encode) {
|
||||||
|
fprintf(stderr, "exactly one of -d or -e must be given\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read all of stdin into src[:s].
|
||||||
|
size_t s = 0;
|
||||||
|
while (1) {
|
||||||
|
if (s == N) {
|
||||||
|
fprintf(stderr, "input too large\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ssize_t n = read(0, src+s, N-s);
|
||||||
|
if (n == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
fprintf(stderr, "read error: %s\n", strerror(errno));
|
||||||
|
// TODO: handle EAGAIN, EINTR?
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
s += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode or decode src[:s] to dst[:d], and write to stdout.
|
||||||
|
size_t d = 0;
|
||||||
|
if (encode) {
|
||||||
|
if (N < snappy::MaxCompressedLength(s)) {
|
||||||
|
fprintf(stderr, "input too large after encoding\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
snappy::RawCompress(src, s, dst, &d);
|
||||||
|
} else {
|
||||||
|
if (!snappy::GetUncompressedLength(src, s, &d)) {
|
||||||
|
fprintf(stderr, "could not get uncompressed length\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (N < d) {
|
||||||
|
fprintf(stderr, "input too large after decoding\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!snappy::RawUncompress(src, s, dst)) {
|
||||||
|
fprintf(stderr, "input was not valid Snappy-compressed data\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write(1, dst, d);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -29,13 +29,28 @@ func TestMaxEncodedLenOfMaxBlockSize(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cmp(a, b []byte) error {
|
||||||
|
if bytes.Equal(a, b) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return fmt.Errorf("got %d bytes, want %d", len(a), len(b))
|
||||||
|
}
|
||||||
|
for i := range a {
|
||||||
|
if a[i] != b[i] {
|
||||||
|
return fmt.Errorf("byte #%d: got 0x%02x, want 0x%02x", i, a[i], b[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func roundtrip(b, ebuf, dbuf []byte) error {
|
func roundtrip(b, ebuf, dbuf []byte) error {
|
||||||
d, err := Decode(dbuf, Encode(ebuf, b))
|
d, err := Decode(dbuf, Encode(ebuf, b))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("decoding error: %v", err)
|
return fmt.Errorf("decoding error: %v", err)
|
||||||
}
|
}
|
||||||
if !bytes.Equal(b, d) {
|
if err := cmp(d, b); err != nil {
|
||||||
return fmt.Errorf("roundtrip mismatch:\n\twant %v\n\tgot %v", b, d)
|
return fmt.Errorf("roundtrip mismatch: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -327,6 +342,24 @@ func TestDecodeLengthOffset(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecodeGoldenInput(t *testing.T) {
|
||||||
|
src, err := ioutil.ReadFile("testdata/pi.txt.rawsnappy")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ReadFile: %v", err)
|
||||||
|
}
|
||||||
|
got, err := Decode(nil, src)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Decode: %v", err)
|
||||||
|
}
|
||||||
|
want, err := ioutil.ReadFile("testdata/pi.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ReadFile: %v", err)
|
||||||
|
}
|
||||||
|
if err := cmp(got, want); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestEncodeNoiseThenRepeats encodes input for which the first half is very
|
// TestEncodeNoiseThenRepeats encodes input for which the first half is very
|
||||||
// incompressible and the second half is very compressible. The encoded form's
|
// incompressible and the second half is very compressible. The encoded form's
|
||||||
// length should be closer to 50% of the original length than 100%.
|
// length should be closer to 50% of the original length than 100%.
|
||||||
|
@ -348,18 +381,6 @@ func TestEncodeNoiseThenRepeats(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmp(a, b []byte) error {
|
|
||||||
if len(a) != len(b) {
|
|
||||||
return fmt.Errorf("got %d bytes, want %d", len(a), len(b))
|
|
||||||
}
|
|
||||||
for i := range a {
|
|
||||||
if a[i] != b[i] {
|
|
||||||
return fmt.Errorf("byte #%d: got 0x%02x, want 0x%02x", i, a[i], b[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFramingFormat(t *testing.T) {
|
func TestFramingFormat(t *testing.T) {
|
||||||
// src is comprised of alternating 1e5-sized sequences of random
|
// src is comprised of alternating 1e5-sized sequences of random
|
||||||
// (incompressible) bytes and repeated (compressible) bytes. 1e5 was chosen
|
// (incompressible) bytes and repeated (compressible) bytes. 1e5 was chosen
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче