mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-29 03:08:47 -06:00
This introduce two new internal values, blobLeaf and compoundBlob. At
this point the compoundBlob only contains blob leafs but a future change will create multiple tiers. Both these implement the new Blob interface. The splitting is done by using a rolling hash over the last 64 bytes, when that hash ends with 13 consecutive ones we split the data. Issue #17
This commit is contained in:
@@ -198,7 +198,9 @@ func getPhotosetPhotos(id string) SetOfPhoto {
|
||||
url := getOriginalUrl(p.Id)
|
||||
fmt.Printf(" . %v\n", url)
|
||||
photoReader := getPhotoReader(url)
|
||||
photo := NewPhoto().SetId(types.NewString(p.Id)).SetTitle(types.NewString(p.Title)).SetUrl(types.NewString(url)).SetImage(types.NewBlob(photoReader))
|
||||
b, err := types.NewBlob(photoReader)
|
||||
Chk.NoError(err)
|
||||
photo := NewPhoto().SetId(types.NewString(p.Id)).SetTitle(types.NewString(p.Title)).SetUrl(types.NewString(url)).SetImage(b)
|
||||
photoSet = photoSet.Insert(photo)
|
||||
}
|
||||
return photoSet
|
||||
|
||||
635
types/alice-short.txt
Normal file
635
types/alice-short.txt
Normal file
@@ -0,0 +1,635 @@
|
||||
Project Gutenberg's Alice's Adventures in Wonderland, by Lewis Carroll
|
||||
|
||||
This eBook is for the use of anyone anywhere at no cost and with
|
||||
almost no restrictions whatsoever. You may copy it, give it away or
|
||||
re-use it under the terms of the Project Gutenberg License included
|
||||
with this eBook or online at www.gutenberg.org
|
||||
|
||||
|
||||
Title: Alice's Adventures in Wonderland
|
||||
|
||||
Author: Lewis Carroll
|
||||
|
||||
Posting Date: June 25, 2008 [EBook #11]
|
||||
Release Date: March, 1994
|
||||
[Last updated: December 20, 2011]
|
||||
|
||||
Language: English
|
||||
|
||||
|
||||
*** START OF THIS PROJECT GUTENBERG EBOOK ALICE'S ADVENTURES IN WONDERLAND ***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ALICE'S ADVENTURES IN WONDERLAND
|
||||
|
||||
Lewis Carroll
|
||||
|
||||
THE MILLENNIUM FULCRUM EDITION 3.0
|
||||
|
||||
|
||||
|
||||
|
||||
CHAPTER I. Down the Rabbit-Hole
|
||||
|
||||
Alice was beginning to get very tired of sitting by her sister on the
|
||||
bank, and of having nothing to do: once or twice she had peeped into the
|
||||
book her sister was reading, but it had no pictures or conversations in
|
||||
it, 'and what is the use of a book,' thought Alice 'without pictures or
|
||||
conversations?'
|
||||
|
||||
So she was considering in her own mind (as well as she could, for the
|
||||
hot day made her feel very sleepy and stupid), whether the pleasure
|
||||
of making a daisy-chain would be worth the trouble of getting up and
|
||||
picking the daisies, when suddenly a White Rabbit with pink eyes ran
|
||||
close by her.
|
||||
|
||||
There was nothing so VERY remarkable in that; nor did Alice think it so
|
||||
VERY much out of the way to hear the Rabbit say to itself, 'Oh dear!
|
||||
Oh dear! I shall be late!' (when she thought it over afterwards, it
|
||||
occurred to her that she ought to have wondered at this, but at the time
|
||||
it all seemed quite natural); but when the Rabbit actually TOOK A WATCH
|
||||
OUT OF ITS WAISTCOAT-POCKET, and looked at it, and then hurried on,
|
||||
Alice started to her feet, for it flashed across her mind that she had
|
||||
never before seen a rabbit with either a waistcoat-pocket, or a watch
|
||||
to take out of it, and burning with curiosity, she ran across the field
|
||||
after it, and fortunately was just in time to see it pop down a large
|
||||
rabbit-hole under the hedge.
|
||||
|
||||
In another moment down went Alice after it, never once considering how
|
||||
in the world she was to get out again.
|
||||
|
||||
The rabbit-hole went straight on like a tunnel for some way, and then
|
||||
dipped suddenly down, so suddenly that Alice had not a moment to think
|
||||
about stopping herself before she found herself falling down a very deep
|
||||
well.
|
||||
|
||||
Either the well was very deep, or she fell very slowly, for she had
|
||||
plenty of time as she went down to look about her and to wonder what was
|
||||
going to happen next. First, she tried to look down and make out what
|
||||
she was coming to, but it was too dark to see anything; then she
|
||||
looked at the sides of the well, and noticed that they were filled with
|
||||
cupboards and book-shelves; here and there she saw maps and pictures
|
||||
hung upon pegs. She took down a jar from one of the shelves as
|
||||
she passed; it was labelled 'ORANGE MARMALADE', but to her great
|
||||
disappointment it was empty: she did not like to drop the jar for fear
|
||||
of killing somebody, so managed to put it into one of the cupboards as
|
||||
she fell past it.
|
||||
|
||||
'Well!' thought Alice to herself, 'after such a fall as this, I shall
|
||||
think nothing of tumbling down stairs! How brave they'll all think me at
|
||||
home! Why, I wouldn't say anything about it, even if I fell off the top
|
||||
of the house!' (Which was very likely true.)
|
||||
|
||||
Down, down, down. Would the fall NEVER come to an end! 'I wonder how
|
||||
many miles I've fallen by this time?' she said aloud. 'I must be getting
|
||||
somewhere near the centre of the earth. Let me see: that would be four
|
||||
thousand miles down, I think--' (for, you see, Alice had learnt several
|
||||
things of this sort in her lessons in the schoolroom, and though this
|
||||
was not a VERY good opportunity for showing off her knowledge, as there
|
||||
was no one to listen to her, still it was good practice to say it over)
|
||||
'--yes, that's about the right distance--but then I wonder what Latitude
|
||||
or Longitude I've got to?' (Alice had no idea what Latitude was, or
|
||||
Longitude either, but thought they were nice grand words to say.)
|
||||
|
||||
Presently she began again. 'I wonder if I shall fall right THROUGH the
|
||||
earth! How funny it'll seem to come out among the people that walk with
|
||||
their heads downward! The Antipathies, I think--' (she was rather glad
|
||||
there WAS no one listening, this time, as it didn't sound at all the
|
||||
right word) '--but I shall have to ask them what the name of the country
|
||||
is, you know. Please, Ma'am, is this New Zealand or Australia?' (and
|
||||
she tried to curtsey as she spoke--fancy CURTSEYING as you're falling
|
||||
through the air! Do you think you could manage it?) 'And what an
|
||||
ignorant little girl she'll think me for asking! No, it'll never do to
|
||||
ask: perhaps I shall see it written up somewhere.'
|
||||
|
||||
Down, down, down. There was nothing else to do, so Alice soon began
|
||||
talking again. 'Dinah'll miss me very much to-night, I should think!'
|
||||
(Dinah was the cat.) 'I hope they'll remember her saucer of milk at
|
||||
tea-time. Dinah my dear! I wish you were down here with me! There are no
|
||||
mice in the air, I'm afraid, but you might catch a bat, and that's very
|
||||
like a mouse, you know. But do cats eat bats, I wonder?' And here Alice
|
||||
began to get rather sleepy, and went on saying to herself, in a dreamy
|
||||
sort of way, 'Do cats eat bats? Do cats eat bats?' and sometimes, 'Do
|
||||
bats eat cats?' for, you see, as she couldn't answer either question,
|
||||
it didn't much matter which way she put it. She felt that she was dozing
|
||||
off, and had just begun to dream that she was walking hand in hand with
|
||||
Dinah, and saying to her very earnestly, 'Now, Dinah, tell me the truth:
|
||||
did you ever eat a bat?' when suddenly, thump! thump! down she came upon
|
||||
a heap of sticks and dry leaves, and the fall was over.
|
||||
|
||||
Alice was not a bit hurt, and she jumped up on to her feet in a moment:
|
||||
she looked up, but it was all dark overhead; before her was another
|
||||
long passage, and the White Rabbit was still in sight, hurrying down it.
|
||||
There was not a moment to be lost: away went Alice like the wind, and
|
||||
was just in time to hear it say, as it turned a corner, 'Oh my ears
|
||||
and whiskers, how late it's getting!' She was close behind it when she
|
||||
turned the corner, but the Rabbit was no longer to be seen: she found
|
||||
herself in a long, low hall, which was lit up by a row of lamps hanging
|
||||
from the roof.
|
||||
|
||||
There were doors all round the hall, but they were all locked; and when
|
||||
Alice had been all the way down one side and up the other, trying every
|
||||
door, she walked sadly down the middle, wondering how she was ever to
|
||||
get out again.
|
||||
|
||||
Suddenly she came upon a little three-legged table, all made of solid
|
||||
glass; there was nothing on it except a tiny golden key, and Alice's
|
||||
first thought was that it might belong to one of the doors of the hall;
|
||||
but, alas! either the locks were too large, or the key was too small,
|
||||
but at any rate it would not open any of them. However, on the second
|
||||
time round, she came upon a low curtain she had not noticed before, and
|
||||
behind it was a little door about fifteen inches high: she tried the
|
||||
little golden key in the lock, and to her great delight it fitted!
|
||||
|
||||
Alice opened the door and found that it led into a small passage, not
|
||||
much larger than a rat-hole: she knelt down and looked along the passage
|
||||
into the loveliest garden you ever saw. How she longed to get out of
|
||||
that dark hall, and wander about among those beds of bright flowers and
|
||||
those cool fountains, but she could not even get her head through the
|
||||
doorway; 'and even if my head would go through,' thought poor Alice, 'it
|
||||
would be of very little use without my shoulders. Oh, how I wish I could
|
||||
shut up like a telescope! I think I could, if I only knew how to begin.'
|
||||
For, you see, so many out-of-the-way things had happened lately,
|
||||
that Alice had begun to think that very few things indeed were really
|
||||
impossible.
|
||||
|
||||
There seemed to be no use in waiting by the little door, so she went
|
||||
back to the table, half hoping she might find another key on it, or at
|
||||
any rate a book of rules for shutting people up like telescopes: this
|
||||
time she found a little bottle on it, ('which certainly was not here
|
||||
before,' said Alice,) and round the neck of the bottle was a paper
|
||||
label, with the words 'DRINK ME' beautifully printed on it in large
|
||||
letters.
|
||||
|
||||
It was all very well to say 'Drink me,' but the wise little Alice was
|
||||
not going to do THAT in a hurry. 'No, I'll look first,' she said, 'and
|
||||
see whether it's marked "poison" or not'; for she had read several nice
|
||||
little histories about children who had got burnt, and eaten up by wild
|
||||
beasts and other unpleasant things, all because they WOULD not remember
|
||||
the simple rules their friends had taught them: such as, that a red-hot
|
||||
poker will burn you if you hold it too long; and that if you cut your
|
||||
finger VERY deeply with a knife, it usually bleeds; and she had never
|
||||
forgotten that, if you drink much from a bottle marked 'poison,' it is
|
||||
almost certain to disagree with you, sooner or later.
|
||||
|
||||
However, this bottle was NOT marked 'poison,' so Alice ventured to taste
|
||||
it, and finding it very nice, (it had, in fact, a sort of mixed flavour
|
||||
of cherry-tart, custard, pine-apple, roast turkey, toffee, and hot
|
||||
buttered toast,) she very soon finished it off.
|
||||
|
||||
* * * * * * *
|
||||
|
||||
* * * * * *
|
||||
|
||||
* * * * * * *
|
||||
|
||||
'What a curious feeling!' said Alice; 'I must be shutting up like a
|
||||
telescope.'
|
||||
|
||||
And so it was indeed: she was now only ten inches high, and her face
|
||||
brightened up at the thought that she was now the right size for going
|
||||
through the little door into that lovely garden. First, however, she
|
||||
waited for a few minutes to see if she was going to shrink any further:
|
||||
she felt a little nervous about this; 'for it might end, you know,' said
|
||||
Alice to herself, 'in my going out altogether, like a candle. I wonder
|
||||
what I should be like then?' And she tried to fancy what the flame of a
|
||||
candle is like after the candle is blown out, for she could not remember
|
||||
ever having seen such a thing.
|
||||
|
||||
After a while, finding that nothing more happened, she decided on going
|
||||
into the garden at once; but, alas for poor Alice! when she got to the
|
||||
door, she found she had forgotten the little golden key, and when she
|
||||
went back to the table for it, she found she could not possibly reach
|
||||
it: she could see it quite plainly through the glass, and she tried her
|
||||
best to climb up one of the legs of the table, but it was too slippery;
|
||||
and when she had tired herself out with trying, the poor little thing
|
||||
sat down and cried.
|
||||
|
||||
'Come, there's no use in crying like that!' said Alice to herself,
|
||||
rather sharply; 'I advise you to leave off this minute!' She generally
|
||||
gave herself very good advice, (though she very seldom followed it),
|
||||
and sometimes she scolded herself so severely as to bring tears into
|
||||
her eyes; and once she remembered trying to box her own ears for having
|
||||
cheated herself in a game of croquet she was playing against herself,
|
||||
for this curious child was very fond of pretending to be two people.
|
||||
'But it's no use now,' thought poor Alice, 'to pretend to be two people!
|
||||
Why, there's hardly enough of me left to make ONE respectable person!'
|
||||
|
||||
Soon her eye fell on a little glass box that was lying under the table:
|
||||
she opened it, and found in it a very small cake, on which the words
|
||||
'EAT ME' were beautifully marked in currants. 'Well, I'll eat it,' said
|
||||
Alice, 'and if it makes me grow larger, I can reach the key; and if it
|
||||
makes me grow smaller, I can creep under the door; so either way I'll
|
||||
get into the garden, and I don't care which happens!'
|
||||
|
||||
She ate a little bit, and said anxiously to herself, 'Which way? Which
|
||||
way?', holding her hand on the top of her head to feel which way it was
|
||||
growing, and she was quite surprised to find that she remained the same
|
||||
size: to be sure, this generally happens when one eats cake, but Alice
|
||||
had got so much into the way of expecting nothing but out-of-the-way
|
||||
things to happen, that it seemed quite dull and stupid for life to go on
|
||||
in the common way.
|
||||
|
||||
So she set to work, and very soon finished off the cake.
|
||||
|
||||
* * * * * * *
|
||||
|
||||
* * * * * *
|
||||
|
||||
* * * * * * *
|
||||
|
||||
|
||||
|
||||
|
||||
CHAPTER II. The Pool of Tears
|
||||
|
||||
'Curiouser and curiouser!' cried Alice (she was so much surprised, that
|
||||
for the moment she quite forgot how to speak good English); 'now I'm
|
||||
opening out like the largest telescope that ever was! Good-bye, feet!'
|
||||
(for when she looked down at her feet, they seemed to be almost out of
|
||||
sight, they were getting so far off). 'Oh, my poor little feet, I wonder
|
||||
who will put on your shoes and stockings for you now, dears? I'm sure
|
||||
_I_ shan't be able! I shall be a great deal too far off to trouble
|
||||
myself about you: you must manage the best way you can;--but I must be
|
||||
kind to them,' thought Alice, 'or perhaps they won't walk the way I want
|
||||
to go! Let me see: I'll give them a new pair of boots every Christmas.'
|
||||
|
||||
And she went on planning to herself how she would manage it. 'They must
|
||||
go by the carrier,' she thought; 'and how funny it'll seem, sending
|
||||
presents to one's own feet! And how odd the directions will look!
|
||||
|
||||
ALICE'S RIGHT FOOT, ESQ.
|
||||
HEARTHRUG,
|
||||
NEAR THE FENDER,
|
||||
(WITH ALICE'S LOVE).
|
||||
|
||||
Oh dear, what nonsense I'm talking!'
|
||||
|
||||
Just then her head struck against the roof of the hall: in fact she was
|
||||
now more than nine feet high, and she at once took up the little golden
|
||||
key and hurried off to the garden door.
|
||||
|
||||
Poor Alice! It was as much as she could do, lying down on one side, to
|
||||
look through into the garden with one eye; but to get through was more
|
||||
hopeless than ever: she sat down and began to cry again.
|
||||
|
||||
'You ought to be ashamed of yourself,' said Alice, 'a great girl like
|
||||
you,' (she might well say this), 'to go on crying in this way! Stop this
|
||||
moment, I tell you!' But she went on all the same, shedding gallons of
|
||||
tears, until there was a large pool all round her, about four inches
|
||||
deep and reaching half down the hall.
|
||||
|
||||
After a time she heard a little pattering of feet in the distance, and
|
||||
she hastily dried her eyes to see what was coming. It was the White
|
||||
Rabbit returning, splendidly dressed, with a pair of white kid gloves in
|
||||
one hand and a large fan in the other: he came trotting along in a great
|
||||
hurry, muttering to himself as he came, 'Oh! the Duchess, the Duchess!
|
||||
Oh! won't she be savage if I've kept her waiting!' Alice felt so
|
||||
desperate that she was ready to ask help of any one; so, when the Rabbit
|
||||
came near her, she began, in a low, timid voice, 'If you please, sir--'
|
||||
The Rabbit started violently, dropped the white kid gloves and the fan,
|
||||
and skurried away into the darkness as hard as he could go.
|
||||
|
||||
Alice took up the fan and gloves, and, as the hall was very hot, she
|
||||
kept fanning herself all the time she went on talking: 'Dear, dear! How
|
||||
queer everything is to-day! And yesterday things went on just as usual.
|
||||
I wonder if I've been changed in the night? Let me think: was I the
|
||||
same when I got up this morning? I almost think I can remember feeling a
|
||||
little different. But if I'm not the same, the next question is, Who
|
||||
in the world am I? Ah, THAT'S the great puzzle!' And she began thinking
|
||||
over all the children she knew that were of the same age as herself, to
|
||||
see if she could have been changed for any of them.
|
||||
|
||||
'I'm sure I'm not Ada,' she said, 'for her hair goes in such long
|
||||
ringlets, and mine doesn't go in ringlets at all; and I'm sure I can't
|
||||
be Mabel, for I know all sorts of things, and she, oh! she knows such a
|
||||
very little! Besides, SHE'S she, and I'm I, and--oh dear, how puzzling
|
||||
it all is! I'll try if I know all the things I used to know. Let me
|
||||
see: four times five is twelve, and four times six is thirteen, and
|
||||
four times seven is--oh dear! I shall never get to twenty at that rate!
|
||||
However, the Multiplication Table doesn't signify: let's try Geography.
|
||||
London is the capital of Paris, and Paris is the capital of Rome, and
|
||||
Rome--no, THAT'S all wrong, I'm certain! I must have been changed for
|
||||
Mabel! I'll try and say "How doth the little--"' and she crossed her
|
||||
hands on her lap as if she were saying lessons, and began to repeat it,
|
||||
but her voice sounded hoarse and strange, and the words did not come the
|
||||
same as they used to do:--
|
||||
|
||||
'How doth the little crocodile
|
||||
Improve his shining tail,
|
||||
And pour the waters of the Nile
|
||||
On every golden scale!
|
||||
|
||||
'How cheerfully he seems to grin,
|
||||
How neatly spread his claws,
|
||||
And welcome little fishes in
|
||||
With gently smiling jaws!'
|
||||
|
||||
'I'm sure those are not the right words,' said poor Alice, and her eyes
|
||||
filled with tears again as she went on, 'I must be Mabel after all, and
|
||||
I shall have to go and live in that poky little house, and have next to
|
||||
no toys to play with, and oh! ever so many lessons to learn! No, I've
|
||||
made up my mind about it; if I'm Mabel, I'll stay down here! It'll be no
|
||||
use their putting their heads down and saying "Come up again, dear!" I
|
||||
shall only look up and say "Who am I then? Tell me that first, and then,
|
||||
if I like being that person, I'll come up: if not, I'll stay down here
|
||||
till I'm somebody else"--but, oh dear!' cried Alice, with a sudden burst
|
||||
of tears, 'I do wish they WOULD put their heads down! I am so VERY tired
|
||||
of being all alone here!'
|
||||
|
||||
As she said this she looked down at her hands, and was surprised to see
|
||||
that she had put on one of the Rabbit's little white kid gloves while
|
||||
she was talking. 'How CAN I have done that?' she thought. 'I must
|
||||
be growing small again.' She got up and went to the table to measure
|
||||
herself by it, and found that, as nearly as she could guess, she was now
|
||||
about two feet high, and was going on shrinking rapidly: she soon found
|
||||
out that the cause of this was the fan she was holding, and she dropped
|
||||
it hastily, just in time to avoid shrinking away altogether.
|
||||
|
||||
'That WAS a narrow escape!' said Alice, a good deal frightened at the
|
||||
sudden change, but very glad to find herself still in existence; 'and
|
||||
now for the garden!' and she ran with all speed back to the little door:
|
||||
but, alas! the little door was shut again, and the little golden key was
|
||||
lying on the glass table as before, 'and things are worse than ever,'
|
||||
thought the poor child, 'for I never was so small as this before, never!
|
||||
And I declare it's too bad, that it is!'
|
||||
|
||||
As she said these words her foot slipped, and in another moment, splash!
|
||||
she was up to her chin in salt water. Her first idea was that she
|
||||
had somehow fallen into the sea, 'and in that case I can go back by
|
||||
railway,' she said to herself. (Alice had been to the seaside once in
|
||||
her life, and had come to the general conclusion, that wherever you go
|
||||
to on the English coast you find a number of bathing machines in the
|
||||
sea, some children digging in the sand with wooden spades, then a row
|
||||
of lodging houses, and behind them a railway station.) However, she soon
|
||||
made out that she was in the pool of tears which she had wept when she
|
||||
was nine feet high.
|
||||
|
||||
'I wish I hadn't cried so much!' said Alice, as she swam about, trying
|
||||
to find her way out. 'I shall be punished for it now, I suppose, by
|
||||
being drowned in my own tears! That WILL be a queer thing, to be sure!
|
||||
However, everything is queer to-day.'
|
||||
|
||||
Just then she heard something splashing about in the pool a little way
|
||||
off, and she swam nearer to make out what it was: at first she thought
|
||||
it must be a walrus or hippopotamus, but then she remembered how small
|
||||
she was now, and she soon made out that it was only a mouse that had
|
||||
slipped in like herself.
|
||||
|
||||
'Would it be of any use, now,' thought Alice, 'to speak to this mouse?
|
||||
Everything is so out-of-the-way down here, that I should think very
|
||||
likely it can talk: at any rate, there's no harm in trying.' So she
|
||||
began: 'O Mouse, do you know the way out of this pool? I am very tired
|
||||
of swimming about here, O Mouse!' (Alice thought this must be the right
|
||||
way of speaking to a mouse: she had never done such a thing before, but
|
||||
she remembered having seen in her brother's Latin Grammar, 'A mouse--of
|
||||
a mouse--to a mouse--a mouse--O mouse!') The Mouse looked at her rather
|
||||
inquisitively, and seemed to her to wink with one of its little eyes,
|
||||
but it said nothing.
|
||||
|
||||
'Perhaps it doesn't understand English,' thought Alice; 'I daresay it's
|
||||
a French mouse, come over with William the Conqueror.' (For, with all
|
||||
her knowledge of history, Alice had no very clear notion how long ago
|
||||
anything had happened.) So she began again: 'Ou est ma chatte?' which
|
||||
was the first sentence in her French lesson-book. The Mouse gave a
|
||||
sudden leap out of the water, and seemed to quiver all over with fright.
|
||||
'Oh, I beg your pardon!' cried Alice hastily, afraid that she had hurt
|
||||
the poor animal's feelings. 'I quite forgot you didn't like cats.'
|
||||
|
||||
'Not like cats!' cried the Mouse, in a shrill, passionate voice. 'Would
|
||||
YOU like cats if you were me?'
|
||||
|
||||
'Well, perhaps not,' said Alice in a soothing tone: 'don't be angry
|
||||
about it. And yet I wish I could show you our cat Dinah: I think you'd
|
||||
take a fancy to cats if you could only see her. She is such a dear quiet
|
||||
thing,' Alice went on, half to herself, as she swam lazily about in the
|
||||
pool, 'and she sits purring so nicely by the fire, licking her paws and
|
||||
washing her face--and she is such a nice soft thing to nurse--and she's
|
||||
such a capital one for catching mice--oh, I beg your pardon!' cried
|
||||
Alice again, for this time the Mouse was bristling all over, and she
|
||||
felt certain it must be really offended. 'We won't talk about her any
|
||||
more if you'd rather not.'
|
||||
|
||||
'We indeed!' cried the Mouse, who was trembling down to the end of his
|
||||
tail. 'As if I would talk on such a subject! Our family always HATED
|
||||
cats: nasty, low, vulgar things! Don't let me hear the name again!'
|
||||
|
||||
'I won't indeed!' said Alice, in a great hurry to change the subject of
|
||||
conversation. 'Are you--are you fond--of--of dogs?' The Mouse did not
|
||||
answer, so Alice went on eagerly: 'There is such a nice little dog near
|
||||
our house I should like to show you! A little bright-eyed terrier, you
|
||||
know, with oh, such long curly brown hair! And it'll fetch things when
|
||||
you throw them, and it'll sit up and beg for its dinner, and all sorts
|
||||
of things--I can't remember half of them--and it belongs to a farmer,
|
||||
you know, and he says it's so useful, it's worth a hundred pounds! He
|
||||
says it kills all the rats and--oh dear!' cried Alice in a sorrowful
|
||||
tone, 'I'm afraid I've offended it again!' For the Mouse was swimming
|
||||
away from her as hard as it could go, and making quite a commotion in
|
||||
the pool as it went.
|
||||
|
||||
So she called softly after it, 'Mouse dear! Do come back again, and we
|
||||
won't talk about cats or dogs either, if you don't like them!' When the
|
||||
Mouse heard this, it turned round and swam slowly back to her: its
|
||||
face was quite pale (with passion, Alice thought), and it said in a low
|
||||
trembling voice, 'Let us get to the shore, and then I'll tell you my
|
||||
history, and you'll understand why it is I hate cats and dogs.'
|
||||
|
||||
It was high time to go, for the pool was getting quite crowded with the
|
||||
birds and animals that had fallen into it: there were a Duck and a Dodo,
|
||||
a Lory and an Eaglet, and several other curious creatures. Alice led the
|
||||
way, and the whole party swam to the shore.
|
||||
|
||||
|
||||
|
||||
|
||||
CHAPTER III. A Caucus-Race and a Long Tale
|
||||
|
||||
They were indeed a queer-looking party that assembled on the bank--the
|
||||
birds with draggled feathers, the animals with their fur clinging close
|
||||
to them, and all dripping wet, cross, and uncomfortable.
|
||||
|
||||
The first question of course was, how to get dry again: they had a
|
||||
consultation about this, and after a few minutes it seemed quite natural
|
||||
to Alice to find herself talking familiarly with them, as if she had
|
||||
known them all her life. Indeed, she had quite a long argument with the
|
||||
Lory, who at last turned sulky, and would only say, 'I am older than
|
||||
you, and must know better'; and this Alice would not allow without
|
||||
knowing how old it was, and, as the Lory positively refused to tell its
|
||||
age, there was no more to be said.
|
||||
|
||||
At last the Mouse, who seemed to be a person of authority among them,
|
||||
called out, 'Sit down, all of you, and listen to me! I'LL soon make you
|
||||
dry enough!' They all sat down at once, in a large ring, with the Mouse
|
||||
in the middle. Alice kept her eyes anxiously fixed on it, for she felt
|
||||
sure she would catch a bad cold if she did not get dry very soon.
|
||||
|
||||
'Ahem!' said the Mouse with an important air, 'are you all ready? This
|
||||
is the driest thing I know. Silence all round, if you please! "William
|
||||
the Conqueror, whose cause was favoured by the pope, was soon submitted
|
||||
to by the English, who wanted leaders, and had been of late much
|
||||
accustomed to usurpation and conquest. Edwin and Morcar, the earls of
|
||||
Mercia and Northumbria--"'
|
||||
|
||||
'Ugh!' said the Lory, with a shiver.
|
||||
|
||||
'I beg your pardon!' said the Mouse, frowning, but very politely: 'Did
|
||||
you speak?'
|
||||
|
||||
'Not I!' said the Lory hastily.
|
||||
|
||||
'I thought you did,' said the Mouse. '--I proceed. "Edwin and Morcar,
|
||||
the earls of Mercia and Northumbria, declared for him: and even Stigand,
|
||||
the patriotic archbishop of Canterbury, found it advisable--"'
|
||||
|
||||
'Found WHAT?' said the Duck.
|
||||
|
||||
'Found IT,' the Mouse replied rather crossly: 'of course you know what
|
||||
"it" means.'
|
||||
|
||||
'I know what "it" means well enough, when I find a thing,' said the
|
||||
Duck: 'it's generally a frog or a worm. The question is, what did the
|
||||
archbishop find?'
|
||||
|
||||
The Mouse did not notice this question, but hurriedly went on, '"--found
|
||||
it advisable to go with Edgar Atheling to meet William and offer him the
|
||||
crown. William's conduct at first was moderate. But the insolence of his
|
||||
Normans--" How are you getting on now, my dear?' it continued, turning
|
||||
to Alice as it spoke.
|
||||
|
||||
'As wet as ever,' said Alice in a melancholy tone: 'it doesn't seem to
|
||||
dry me at all.'
|
||||
|
||||
'In that case,' said the Dodo solemnly, rising to its feet, 'I move
|
||||
that the meeting adjourn, for the immediate adoption of more energetic
|
||||
remedies--'
|
||||
|
||||
'Speak English!' said the Eaglet. 'I don't know the meaning of half
|
||||
those long words, and, what's more, I don't believe you do either!' And
|
||||
the Eaglet bent down its head to hide a smile: some of the other birds
|
||||
tittered audibly.
|
||||
|
||||
'What I was going to say,' said the Dodo in an offended tone, 'was, that
|
||||
the best thing to get us dry would be a Caucus-race.'
|
||||
|
||||
'What IS a Caucus-race?' said Alice; not that she wanted much to know,
|
||||
but the Dodo had paused as if it thought that SOMEBODY ought to speak,
|
||||
and no one else seemed inclined to say anything.
|
||||
|
||||
'Why,' said the Dodo, 'the best way to explain it is to do it.' (And, as
|
||||
you might like to try the thing yourself, some winter day, I will tell
|
||||
you how the Dodo managed it.)
|
||||
|
||||
First it marked out a race-course, in a sort of circle, ('the exact
|
||||
shape doesn't matter,' it said,) and then all the party were placed
|
||||
along the course, here and there. There was no 'One, two, three, and
|
||||
away,' but they began running when they liked, and left off when they
|
||||
liked, so that it was not easy to know when the race was over. However,
|
||||
when they had been running half an hour or so, and were quite dry again,
|
||||
the Dodo suddenly called out 'The race is over!' and they all crowded
|
||||
round it, panting, and asking, 'But who has won?'
|
||||
|
||||
This question the Dodo could not answer without a great deal of thought,
|
||||
and it sat for a long time with one finger pressed upon its forehead
|
||||
(the position in which you usually see Shakespeare, in the pictures
|
||||
of him), while the rest waited in silence. At last the Dodo said,
|
||||
'EVERYBODY has won, and all must have prizes.'
|
||||
|
||||
'But who is to give the prizes?' quite a chorus of voices asked.
|
||||
|
||||
'Why, SHE, of course,' said the Dodo, pointing to Alice with one finger;
|
||||
and the whole party at once crowded round her, calling out in a confused
|
||||
way, 'Prizes! Prizes!'
|
||||
|
||||
Alice had no idea what to do, and in despair she put her hand in her
|
||||
pocket, and pulled out a box of comfits, (luckily the salt water had
|
||||
not got into it), and handed them round as prizes. There was exactly one
|
||||
a-piece all round.
|
||||
|
||||
'But she must have a prize herself, you know,' said the Mouse.
|
||||
|
||||
'Of course,' the Dodo replied very gravely. 'What else have you got in
|
||||
your pocket?' he went on, turning to Alice.
|
||||
|
||||
'Only a thimble,' said Alice sadly.
|
||||
|
||||
'Hand it over here,' said the Dodo.
|
||||
|
||||
Then they all crowded round her once more, while the Dodo solemnly
|
||||
presented the thimble, saying 'We beg your acceptance of this elegant
|
||||
thimble'; and, when it had finished this short speech, they all cheered.
|
||||
|
||||
Alice thought the whole thing very absurd, but they all looked so grave
|
||||
that she did not dare to laugh; and, as she could not think of anything
|
||||
to say, she simply bowed, and took the thimble, looking as solemn as she
|
||||
could.
|
||||
|
||||
The next thing was to eat the comfits: this caused some noise and
|
||||
confusion, as the large birds complained that they could not taste
|
||||
theirs, and the small ones choked and had to be patted on the back.
|
||||
However, it was over at last, and they sat down again in a ring, and
|
||||
begged the Mouse to tell them something more.
|
||||
|
||||
'You promised to tell me your history, you know,' said Alice, 'and why
|
||||
it is you hate--C and D,' she added in a whisper, half afraid that it
|
||||
would be offended again.
|
||||
|
||||
'Mine is a long and a sad tale!' said the Mouse, turning to Alice, and
|
||||
sighing.
|
||||
|
||||
'It IS a long tail, certainly,' said Alice, looking down with wonder at
|
||||
the Mouse's tail; 'but why do you call it sad?' And she kept on puzzling
|
||||
about it while the Mouse was speaking, so that her idea of the tale was
|
||||
something like this:--
|
||||
|
||||
'Fury said to a
|
||||
mouse, That he
|
||||
met in the
|
||||
house,
|
||||
"Let us
|
||||
both go to
|
||||
law: I will
|
||||
prosecute
|
||||
YOU.--Come,
|
||||
I'll take no
|
||||
denial; We
|
||||
must have a
|
||||
trial: For
|
||||
really this
|
||||
morning I've
|
||||
nothing
|
||||
to do."
|
||||
Said the
|
||||
mouse to the
|
||||
cur, "Such
|
||||
a trial,
|
||||
dear Sir,
|
||||
With
|
||||
no jury
|
||||
or judge,
|
||||
would be
|
||||
wasting
|
||||
our
|
||||
breath."
|
||||
"I'll be
|
||||
judge, I'll
|
||||
be jury,"
|
||||
Said
|
||||
cunning
|
||||
old Fury:
|
||||
"I'll
|
||||
try the
|
||||
whole
|
||||
cause,
|
||||
and
|
||||
condemn
|
||||
you
|
||||
to
|
||||
death."'
|
||||
@@ -3,47 +3,90 @@ package types
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/attic-labs/noms/dbg"
|
||||
"github.com/attic-labs/buzhash"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
type Blob struct {
|
||||
data []byte
|
||||
ref *ref.Ref
|
||||
const (
|
||||
// 12 bits leads to an average size of 4k
|
||||
// 13 bits leads to an average size of 8k
|
||||
// 14 bits leads to an average size of 16k
|
||||
pattern = uint32(1<<13 - 1)
|
||||
|
||||
// The window size to use for computing the rolling hash.
|
||||
windowSize = 64
|
||||
)
|
||||
|
||||
type Blob interface {
|
||||
Value
|
||||
Len() uint64
|
||||
// BUG 155 - Should provide Seek and Write... Maybe even have Blob implement ReadWriteSeeker
|
||||
Reader() io.Reader
|
||||
}
|
||||
|
||||
func (fb Blob) Reader() io.Reader {
|
||||
return bytes.NewBuffer(fb.data)
|
||||
}
|
||||
func NewBlob(r io.Reader) (Blob, error) {
|
||||
length := uint64(0)
|
||||
childLengths := []uint64{}
|
||||
blobs := []Future{}
|
||||
var blob blobLeaf
|
||||
for {
|
||||
buf := bytes.Buffer{}
|
||||
n, err := copyChunk(&buf, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (fb Blob) Len() uint64 {
|
||||
return uint64(len(fb.data))
|
||||
}
|
||||
if n == 0 {
|
||||
// Don't add empty chunk.
|
||||
break
|
||||
}
|
||||
|
||||
func (fb Blob) Ref() ref.Ref {
|
||||
return ensureRef(fb.ref, fb)
|
||||
}
|
||||
|
||||
func (fb Blob) Equals(other Value) bool {
|
||||
if other == nil {
|
||||
return false
|
||||
} else {
|
||||
return fb.Ref() == other.Ref()
|
||||
length += n
|
||||
blob = newBlobLeaf(buf.Bytes())
|
||||
childLengths = append(childLengths, blob.Len())
|
||||
blobs = append(blobs, futureFromValue(blob))
|
||||
}
|
||||
}
|
||||
|
||||
func (fb Blob) Chunks() []Future {
|
||||
return nil
|
||||
}
|
||||
if length == 0 {
|
||||
return newBlobLeaf([]byte{}), nil
|
||||
}
|
||||
|
||||
func NewBlob(r io.Reader) Blob {
|
||||
data, err := ioutil.ReadAll(r)
|
||||
dbg.Chk.NoError(err)
|
||||
return Blob{data, &ref.Ref{}}
|
||||
if len(blobs) == 1 {
|
||||
return blob, nil
|
||||
}
|
||||
return compoundBlob{length, childLengths, blobs, &ref.Ref{}, nil}, nil
|
||||
}
|
||||
|
||||
func BlobFromVal(v Value) Blob {
|
||||
return v.(Blob)
|
||||
}
|
||||
|
||||
// copyChunk copies from src to dst until a chunk boundary is found.
|
||||
// It returns the number of bytes copied and the earliest error encountered while copying.
|
||||
// copyChunk never returns an io.EOF error, instead it returns the number of bytes read up to the io.EOF.
|
||||
func copyChunk(dst io.Writer, src io.Reader) (n uint64, err error) {
|
||||
h := buzhash.NewBuzHash(windowSize)
|
||||
p := []byte{0}
|
||||
|
||||
for {
|
||||
_, err = src.Read(p)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return n, nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
h.Write(p)
|
||||
_, err = dst.Write(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n++
|
||||
|
||||
if h.Sum32()&pattern == pattern {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
var (
|
||||
blobTag = []byte("b ")
|
||||
)
|
||||
|
||||
func blobEncode(b Blob, s chunks.ChunkSink) (r ref.Ref, err error) {
|
||||
w := s.Put()
|
||||
if _, err = w.Write(blobTag); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = io.Copy(w, b.Reader()); err != nil {
|
||||
return
|
||||
}
|
||||
return w.Ref()
|
||||
}
|
||||
|
||||
func blobDecode(r io.Reader, s chunks.ChunkSource) (Value, error) {
|
||||
// Skip the blobTag
|
||||
_, err := ioutil.ReadAll(io.LimitReader(r, int64(len(blobTag))))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewBlob(r), nil
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBlobCodec(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
dir, err := ioutil.TempDir(os.TempDir(), "")
|
||||
defer os.Remove(dir)
|
||||
assert.NoError(err)
|
||||
fs := chunks.NewFileStore(dir, "root")
|
||||
b1 := NewBlob(&bytes.Buffer{})
|
||||
r1, err := blobEncode(b1, fs)
|
||||
// echo -n 'b ' | sha1sum
|
||||
assert.Equal("sha1-e1bc846440ec2fb557a5a271e785cd4c648883fa", r1.String())
|
||||
|
||||
b2 := NewBlob(bytes.NewBufferString("Hello, World!"))
|
||||
r2, err := blobEncode(b2, fs)
|
||||
// echo -n 'b Hello, World!' | sha1sum
|
||||
assert.Equal("sha1-135fe1453330547994b2ce8a1b238adfbd7df87e", r2.String())
|
||||
|
||||
reader, err := fs.Get(r1)
|
||||
assert.NoError(err)
|
||||
v1, err := blobDecode(reader, fs)
|
||||
assert.NoError(err)
|
||||
assert.True(b1.Equals(v1))
|
||||
|
||||
reader, err = fs.Get(r2)
|
||||
assert.NoError(err)
|
||||
v2, err := blobDecode(reader, fs)
|
||||
assert.NoError(err)
|
||||
assert.True(b2.Equals(v2))
|
||||
}
|
||||
45
types/blob_leaf.go
Normal file
45
types/blob_leaf.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
// blobLeaf represents a leaf in a compoundBlob.
|
||||
// It implements the Blob interface.
|
||||
type blobLeaf struct {
|
||||
data []byte
|
||||
ref *ref.Ref
|
||||
}
|
||||
|
||||
func newBlobLeaf(data []byte) blobLeaf {
|
||||
return blobLeaf{data, &ref.Ref{}}
|
||||
}
|
||||
|
||||
// Reader implements the Blob interface
|
||||
func (bl blobLeaf) Reader() io.Reader {
|
||||
return bytes.NewBuffer(bl.data)
|
||||
}
|
||||
|
||||
// Len implements the Blob interface
|
||||
func (bl blobLeaf) Len() uint64 {
|
||||
return uint64(len(bl.data))
|
||||
}
|
||||
|
||||
func (bl blobLeaf) Ref() ref.Ref {
|
||||
return ensureRef(bl.ref, bl)
|
||||
}
|
||||
|
||||
func (bl blobLeaf) Chunks() []Future {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fb blobLeaf) Equals(other Value) bool {
|
||||
if other == nil {
|
||||
return false
|
||||
} else {
|
||||
return fb.Ref() == other.Ref()
|
||||
}
|
||||
}
|
||||
41
types/blob_leaf_codec.go
Normal file
41
types/blob_leaf_codec.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
. "github.com/attic-labs/noms/dbg"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
var (
|
||||
blobTag = []byte("b ")
|
||||
)
|
||||
|
||||
func blobLeafEncode(b blobLeaf, s chunks.ChunkSink) (r ref.Ref, err error) {
|
||||
w := s.Put()
|
||||
if _, err = w.Write(blobTag); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = io.Copy(w, b.Reader()); err != nil {
|
||||
return
|
||||
}
|
||||
return w.Ref()
|
||||
}
|
||||
|
||||
func blobLeafDecode(r io.Reader, s chunks.ChunkSource) (Value, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
_, err := io.CopyN(buf, r, int64(len(blobTag)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Chk.True(bytes.Equal(buf.Bytes(), blobTag))
|
||||
|
||||
buf.Truncate(0)
|
||||
_, err = io.Copy(buf, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newBlobLeaf(buf.Bytes()), nil
|
||||
}
|
||||
48
types/blob_leaf_codec_test.go
Normal file
48
types/blob_leaf_codec_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBlobLeafEncode(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := &chunks.MemoryStore{}
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
b1, err := NewBlob(buf)
|
||||
assert.NoError(err)
|
||||
bl1, ok := b1.(blobLeaf)
|
||||
assert.True(ok)
|
||||
r1, err := blobLeafEncode(bl1, cs)
|
||||
// echo -n 'b ' | sha1sum
|
||||
assert.Equal("sha1-e1bc846440ec2fb557a5a271e785cd4c648883fa", r1.String())
|
||||
|
||||
buf = bytes.NewBufferString("Hello, World!")
|
||||
b2, err := NewBlob(buf)
|
||||
assert.NoError(err)
|
||||
bl2, ok := b2.(blobLeaf)
|
||||
assert.True(ok)
|
||||
r2, err := blobLeafEncode(bl2, cs)
|
||||
// echo -n 'b Hello, World!' | sha1sum
|
||||
assert.Equal("sha1-135fe1453330547994b2ce8a1b238adfbd7df87e", r2.String())
|
||||
}
|
||||
|
||||
func TestBlobLeafDecode(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
reader := bytes.NewBufferString("b ")
|
||||
v1, err := blobLeafDecode(reader, nil)
|
||||
assert.NoError(err)
|
||||
bl1 := newBlobLeaf([]byte{})
|
||||
assert.True(bl1.Equals(v1))
|
||||
|
||||
reader = bytes.NewBufferString("b Hello World!")
|
||||
v2, err := blobLeafDecode(reader, nil)
|
||||
assert.NoError(err)
|
||||
bl2 := newBlobLeaf([]byte("Hello World!"))
|
||||
assert.True(bl2.Equals(v2))
|
||||
}
|
||||
37
types/blob_leaf_test.go
Normal file
37
types/blob_leaf_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBlobLeafLen(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
b := newBlobLeaf([]byte{})
|
||||
assert.Equal(uint64(0), b.Len())
|
||||
b = newBlobLeaf([]byte{0x01})
|
||||
assert.Equal(uint64(1), b.Len())
|
||||
}
|
||||
|
||||
func TestBlobLeafEquals(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
b1 := newBlobLeaf([]byte{0x01})
|
||||
b11 := b1
|
||||
b12 := newBlobLeaf([]byte{0x01})
|
||||
b2 := newBlobLeaf([]byte{0x02})
|
||||
b3 := newBlobLeaf([]byte{0x02, 0x03})
|
||||
AssertSymEq(assert, b1, b11)
|
||||
AssertSymEq(assert, b1, b12)
|
||||
AssertSymNe(assert, b1, b2)
|
||||
AssertSymNe(assert, b2, b3)
|
||||
AssertSymNe(assert, b1, Int32(1))
|
||||
}
|
||||
|
||||
func TestBlobLeafChunks(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
b := newBlobLeaf([]byte{})
|
||||
assert.Equal(0, len(b.Chunks()))
|
||||
b = newBlobLeaf([]byte{0x01})
|
||||
assert.Equal(0, len(b.Chunks()))
|
||||
}
|
||||
@@ -19,19 +19,21 @@ func AssertSymNe(assert *assert.Assertions, a, b Value) {
|
||||
|
||||
func TestBlobLen(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
b := NewBlob(&bytes.Buffer{})
|
||||
b, err := NewBlob(&bytes.Buffer{})
|
||||
assert.NoError(err)
|
||||
assert.Equal(uint64(0), b.Len())
|
||||
b = NewBlob(bytes.NewBuffer([]byte{0x01}))
|
||||
b, err = NewBlob(bytes.NewBuffer([]byte{0x01}))
|
||||
assert.NoError(err)
|
||||
assert.Equal(uint64(1), b.Len())
|
||||
}
|
||||
|
||||
func TestBlobEquals(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
b1 := NewBlob(bytes.NewBuffer([]byte{0x01}))
|
||||
b1, _ := NewBlob(bytes.NewBuffer([]byte{0x01}))
|
||||
b11 := b1
|
||||
b12 := NewBlob(bytes.NewBuffer([]byte{0x01}))
|
||||
b2 := NewBlob(bytes.NewBuffer([]byte{0x02}))
|
||||
b3 := NewBlob(bytes.NewBuffer([]byte{0x02, 0x03}))
|
||||
b12, _ := NewBlob(bytes.NewBuffer([]byte{0x01}))
|
||||
b2, _ := NewBlob(bytes.NewBuffer([]byte{0x02}))
|
||||
b3, _ := NewBlob(bytes.NewBuffer([]byte{0x02, 0x03}))
|
||||
AssertSymEq(assert, b1, b11)
|
||||
AssertSymEq(assert, b1, b12)
|
||||
AssertSymNe(assert, b1, b2)
|
||||
|
||||
58
types/compound_blob.go
Normal file
58
types/compound_blob.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/attic-labs/noms/dbg"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
// compoundBlob represents a list of Blobs.
|
||||
// It implements the Blob interface.
|
||||
type compoundBlob struct {
|
||||
length uint64
|
||||
childLengths []uint64
|
||||
blobs []Future
|
||||
ref *ref.Ref
|
||||
cs chunks.ChunkSource
|
||||
}
|
||||
|
||||
// Reader implements the Blob interface
|
||||
func (cb compoundBlob) Reader() io.Reader {
|
||||
readers := make([]io.Reader, len(cb.blobs))
|
||||
for i, b := range cb.blobs {
|
||||
// BUG 155 - Should provide Seek and Write... Maybe even have Blob implement ReadWriteSeeker
|
||||
v, err := b.Deref(cb.cs)
|
||||
// TODO: This is ugly. See comment in list.go@Get.
|
||||
dbg.Chk.NoError(err)
|
||||
readers[i] = v.(blobLeaf).Reader()
|
||||
}
|
||||
return io.MultiReader(readers...)
|
||||
}
|
||||
|
||||
// Len implements the Blob interface
|
||||
func (cb compoundBlob) Len() uint64 {
|
||||
return cb.length
|
||||
}
|
||||
|
||||
func (cb compoundBlob) Ref() ref.Ref {
|
||||
return ensureRef(cb.ref, cb)
|
||||
}
|
||||
|
||||
func (cb compoundBlob) Equals(other Value) bool {
|
||||
if other == nil {
|
||||
return false
|
||||
} else {
|
||||
return cb.Ref() == other.Ref()
|
||||
}
|
||||
}
|
||||
|
||||
func (cb compoundBlob) Chunks() (futures []Future) {
|
||||
for _, f := range cb.blobs {
|
||||
if f, ok := f.(*unresolvedFuture); ok {
|
||||
futures = append(futures, f)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
78
types/compound_blob_test.go
Normal file
78
types/compound_blob_test.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func getTestCompoundBlob(datas ...string) compoundBlob {
|
||||
blobs := make([]Future, len(datas))
|
||||
childLengths := make([]uint64, len(datas))
|
||||
length := uint64(0)
|
||||
for i, s := range datas {
|
||||
b, _ := NewBlob(bytes.NewBufferString(s))
|
||||
blobs[i] = futureFromValue(b)
|
||||
childLengths[i] = uint64(len(s))
|
||||
length += uint64(len(s))
|
||||
}
|
||||
return compoundBlob{length, childLengths, blobs, &ref.Ref{}, nil}
|
||||
}
|
||||
|
||||
func getAliceBlob(t *testing.T) compoundBlob {
|
||||
assert := assert.New(t)
|
||||
f, err := os.Open("alice-short.txt")
|
||||
assert.NoError(err)
|
||||
defer f.Close()
|
||||
|
||||
b, err := NewBlob(f)
|
||||
assert.NoError(err)
|
||||
cb, ok := b.(compoundBlob)
|
||||
assert.True(ok)
|
||||
return cb
|
||||
}
|
||||
|
||||
func TestCompoundBlobReader(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cb := getTestCompoundBlob("hello", "world")
|
||||
bs, err := ioutil.ReadAll(cb.Reader())
|
||||
assert.NoError(err)
|
||||
assert.Equal("helloworld", string(bs))
|
||||
|
||||
ab := getAliceBlob(t)
|
||||
bs, err = ioutil.ReadAll(ab.Reader())
|
||||
assert.NoError(err)
|
||||
f, err := os.Open("alice-short.txt")
|
||||
assert.NoError(err)
|
||||
defer f.Close()
|
||||
bs2, err := ioutil.ReadAll(f)
|
||||
assert.Equal(bs2, bs)
|
||||
}
|
||||
|
||||
func TestCompoundBlobLen(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cb := getTestCompoundBlob("hello", "world")
|
||||
assert.Equal(uint64(10), cb.Len())
|
||||
|
||||
ab := getAliceBlob(t)
|
||||
assert.Equal(uint64(30157), ab.Len())
|
||||
}
|
||||
|
||||
func TestCompoundBlobChunks(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := &chunks.MemoryStore{}
|
||||
|
||||
cb := getTestCompoundBlob("hello", "world")
|
||||
assert.Equal(0, len(cb.Chunks()))
|
||||
|
||||
bl1 := newBlobLeaf([]byte("hello"))
|
||||
blr1 := bl1.Ref()
|
||||
bl2 := newBlobLeaf([]byte("world"))
|
||||
cb = compoundBlob{uint64(10), []uint64{5, 5}, []Future{futureFromRef(blr1), futureFromValue(bl2)}, &ref.Ref{}, cs}
|
||||
assert.Equal(1, len(cb.Chunks()))
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -38,9 +39,23 @@ func TestPrimitiveEquals(t *testing.T) {
|
||||
func() Value { return NewString("") },
|
||||
func() Value { return NewString("hi") },
|
||||
func() Value { return NewString("bye") },
|
||||
func() Value { return NewBlob(&bytes.Buffer{}) },
|
||||
func() Value { return NewBlob(bytes.NewBufferString("hi")) },
|
||||
func() Value { return NewBlob(bytes.NewBufferString("bye")) },
|
||||
func() Value {
|
||||
v, _ := NewBlob(&bytes.Buffer{})
|
||||
return v
|
||||
},
|
||||
func() Value {
|
||||
v, _ := NewBlob(bytes.NewBufferString("hi"))
|
||||
return v
|
||||
},
|
||||
func() Value {
|
||||
v, _ := NewBlob(bytes.NewBufferString("bye"))
|
||||
return v
|
||||
},
|
||||
func() Value {
|
||||
b1, _ := NewBlob(bytes.NewBufferString("hi"))
|
||||
b2, _ := NewBlob(bytes.NewBufferString("bye"))
|
||||
return compoundBlob{uint64(5), []uint64{2, 3}, []Future{futureFromValue(b1), futureFromValue(b2)}, &ref.Ref{}, nil}
|
||||
},
|
||||
func() Value { return NewList() },
|
||||
func() Value { return NewList(NewString("foo")) },
|
||||
func() Value { return NewList(NewString("bar")) },
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -20,6 +20,7 @@ func TestGetRef(t *testing.T) {
|
||||
|
||||
func TestEnsureRef(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := &chunks.MemoryStore{}
|
||||
count := byte(1)
|
||||
mockGetRef := func(v Value) ref.Ref {
|
||||
d := ref.Sha1Digest{}
|
||||
@@ -40,8 +41,12 @@ func TestEnsureRef(t *testing.T) {
|
||||
getRefOverride = nil
|
||||
}()
|
||||
|
||||
bl := newBlobLeaf([]byte("hi"))
|
||||
cb := compoundBlob{uint64(2), []uint64{2}, []Future{futureFromValue(bl)}, &ref.Ref{}, cs}
|
||||
|
||||
values := []Value{
|
||||
NewBlob(&bytes.Buffer{}),
|
||||
newBlobLeaf([]byte{}),
|
||||
cb,
|
||||
NewList(),
|
||||
NewString(""),
|
||||
NewMap(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
@@ -20,7 +19,8 @@ var (
|
||||
Float32(1),
|
||||
Float64(1),
|
||||
NewString("hi"),
|
||||
NewBlob(bytes.NewBufferString("hi")),
|
||||
newBlobLeaf([]byte("hi")),
|
||||
// compoundBlob
|
||||
NewSet(NewString("hi")),
|
||||
NewList(NewString("hi")),
|
||||
NewMap(NewString("hi"), NewString("hi")),
|
||||
@@ -29,7 +29,7 @@ var (
|
||||
|
||||
func isEncodedOutOfLine(v Value) int {
|
||||
switch v.(type) {
|
||||
case Blob, Set, List, Map:
|
||||
case blobLeaf, compoundBlob, Set, List, Map:
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
|
||||
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@@ -10,6 +11,8 @@ import (
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
var errInvalidEncoding = errors.New("Invalid encoding")
|
||||
|
||||
func jsonDecode(reader io.Reader, s chunks.ChunkSource) (Value, error) {
|
||||
prefix := make([]byte, len(jsonTag))
|
||||
_, err := io.ReadFull(reader, prefix)
|
||||
@@ -56,6 +59,10 @@ func jsonDecodeTaggedValue(m map[string]interface{}, s chunks.ChunkSource) (Futu
|
||||
Chk.Equal(1, len(m))
|
||||
for k, v := range m {
|
||||
switch k {
|
||||
case "cb":
|
||||
if v, ok := v.([]interface{}); ok {
|
||||
return jsonDecodeCompoundBlob(v, s)
|
||||
}
|
||||
case "int16", "int32", "int64", "uint16", "uint32", "uint64", "float32", "float64":
|
||||
// Go decodes all JSON numbers as float64
|
||||
if v, ok := v.(float64); ok {
|
||||
@@ -146,3 +153,45 @@ func jsonDecodeRef(refStr string, s chunks.ChunkSource) (Future, error) {
|
||||
}
|
||||
return futureFromRef(ref), nil
|
||||
}
|
||||
|
||||
func toUint64(v interface{}) (uint64, error) {
|
||||
fl, ok := v.(float64)
|
||||
if !ok {
|
||||
return 0, errInvalidEncoding
|
||||
}
|
||||
i := uint64(fl)
|
||||
if float64(i) != fl {
|
||||
return 0, errInvalidEncoding
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// [length,length0,{"ref":"sha1-0"}, ... lengthN, {"ref":"sha1-N"}]
|
||||
func jsonDecodeCompoundBlob(input []interface{}, cs chunks.ChunkSource) (Future, error) {
|
||||
if len(input)%2 != 1 {
|
||||
return nil, errInvalidEncoding
|
||||
}
|
||||
|
||||
length, err := toUint64(input[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
numBlobs := len(input) / 2
|
||||
childLengths := make([]uint64, numBlobs)
|
||||
blobs := make([]Future, numBlobs)
|
||||
|
||||
for i := 1; i < len(input); i += 2 {
|
||||
childLength, err := toUint64(input[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
childLengths[i/2] = childLength
|
||||
blobs[i/2], err = jsonDecodeValue(input[i+1], cs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
cb := compoundBlob{length, childLengths, blobs, &ref.Ref{}, cs}
|
||||
return futureFromValue(cb), nil
|
||||
}
|
||||
|
||||
@@ -5,12 +5,13 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestJSONDecode(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := chunks.MemoryStore{}
|
||||
cs := &chunks.MemoryStore{}
|
||||
|
||||
put := func(s string) {
|
||||
s += "\n"
|
||||
@@ -26,7 +27,7 @@ func TestJSONDecode(t *testing.T) {
|
||||
put(`j {"map":[]}`)
|
||||
|
||||
testDecode := func(s string, expected Value) {
|
||||
actual, err := jsonDecode(strings.NewReader(s), &cs)
|
||||
actual, err := jsonDecode(strings.NewReader(s), cs)
|
||||
assert.NoError(err)
|
||||
assert.True(expected.Equals(actual), "Expected decoded value: %s to equal: %+v, but was: %+v", s, expected, actual)
|
||||
}
|
||||
@@ -75,5 +76,45 @@ func TestJSONDecode(t *testing.T) {
|
||||
testDecode(`j {"set":[{"int32":42},"hotdog",{"ref":"sha1-58bdf8e374b39f9b1e8a64784cf5c09601f4b7ea"},false,{"ref":"sha1-dca2a4be23d4455487bb588c6a0ab1b9ee07757e"}]}
|
||||
`, NewSet(Bool(false), Int32(42), NewString("hotdog"), NewList(), NewMap()))
|
||||
|
||||
// referenced blobs?
|
||||
// Blob (compound)
|
||||
// echo -n 'b Hello' | sha1sum
|
||||
blr := ref.MustParse("sha1-c35018551e725bd2ab45166b69d15fda00b161c1")
|
||||
cb := compoundBlob{uint64(2), []uint64{2}, []Future{futureFromRef(blr)}, &ref.Ref{}, cs}
|
||||
testDecode(`j {"cb":[2,2,{"ref":"sha1-c35018551e725bd2ab45166b69d15fda00b161c1"}]}
|
||||
`, cb)
|
||||
// echo -n 'b ' | sha1sum
|
||||
blr2 := ref.MustParse("sha1-641283a12b475ed58ba510517c1224a912e934a6")
|
||||
// echo -n 'b World!' | sha1sum
|
||||
blr3 := ref.MustParse("sha1-8169c017ce2779f3f66bfe27ee2313d71f7698b9")
|
||||
cb2 := compoundBlob{uint64(12), []uint64{5, 1, 6}, []Future{futureFromRef(blr), futureFromRef(blr2), futureFromRef(blr3)}, &ref.Ref{}, cs}
|
||||
testDecode(`j {"cb":[12,5,{"ref":"sha1-c35018551e725bd2ab45166b69d15fda00b161c1"},1,{"ref":"sha1-641283a12b475ed58ba510517c1224a912e934a6"},6,{"ref":"sha1-8169c017ce2779f3f66bfe27ee2313d71f7698b9"}]}
|
||||
`, cb2)
|
||||
}
|
||||
|
||||
func TestCompoundBlobJSONDecodeInvalidFormat(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := &chunks.MemoryStore{}
|
||||
|
||||
_, err := jsonDecode(strings.NewReader("j {\"cb\":[]}\n"), cs)
|
||||
assert.Error(err)
|
||||
_, err = jsonDecode(strings.NewReader("j {\"cb\":[2, 2]}\n"), cs)
|
||||
assert.Error(err)
|
||||
|
||||
_, err = jsonDecode(strings.NewReader("j {\"cb\":[true]}\n"), cs)
|
||||
assert.Error(err)
|
||||
_, err = jsonDecode(strings.NewReader("j {\"cb\":[\"hi\"]}\n"), cs)
|
||||
assert.Error(err)
|
||||
_, err = jsonDecode(strings.NewReader("j {\"cb\":[2.5]}\n"), cs)
|
||||
assert.Error(err)
|
||||
|
||||
_, err = jsonDecode(strings.NewReader(`j {"cb":[2,2.5,"{"ref":"sha1-c35018551e725bd2ab45166b69d15fda00b161c1"}]}
|
||||
`), cs)
|
||||
assert.Error(err)
|
||||
|
||||
_, err = jsonDecode(strings.NewReader("j {\"cb\":[2,2,42]}\n"), cs)
|
||||
assert.Error(err)
|
||||
|
||||
_, err = jsonDecode(strings.NewReader(`j {"cb":[2,2,{"ref":"invalid ref"}]}
|
||||
`), cs)
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
@@ -32,10 +32,12 @@ func jsonEncode(v Value, s chunks.ChunkSink) (r ref.Ref, err error) {
|
||||
|
||||
func getJSON(v Value, s chunks.ChunkSink) (interface{}, error) {
|
||||
switch v := v.(type) {
|
||||
case Blob:
|
||||
case blobLeaf:
|
||||
Chk.Fail(fmt.Sprintf("jsonEncode doesn't support encoding blobs - didn't expect to get here: %+v", v))
|
||||
case Bool:
|
||||
return bool(v), nil
|
||||
case compoundBlob:
|
||||
return getJSONCompoundBlob(v, s)
|
||||
case Float32:
|
||||
return map[string]interface{}{
|
||||
"float32": float32(v),
|
||||
@@ -160,24 +162,33 @@ func getChildJSON(f Future, s chunks.ChunkSink) (interface{}, error) {
|
||||
Chk.NotNil(v)
|
||||
switch v := v.(type) {
|
||||
// Blobs, lists, maps, and sets are always out-of-line
|
||||
case Blob:
|
||||
r, err = WriteValue(v, s)
|
||||
case List:
|
||||
r, err = WriteValue(v, s)
|
||||
case Map:
|
||||
r, err = WriteValue(v, s)
|
||||
case Set:
|
||||
case Blob, List, Map, Set:
|
||||
r, err = WriteValue(v, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
// Other types are always inline.
|
||||
return getJSON(v, s)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
Chk.NotNil(r)
|
||||
return map[string]interface{}{
|
||||
"ref": r.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getJSONCompoundBlob(cb compoundBlob, s chunks.ChunkSink) (interface{}, error) {
|
||||
var err error
|
||||
l := make([]interface{}, len(cb.blobs)*2+1)
|
||||
l[0] = cb.length
|
||||
for i, f := range cb.blobs {
|
||||
l[i*2+1] = cb.childLengths[i]
|
||||
if l[i*2+2], err = getChildJSON(f, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"cb": l,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
@@ -86,6 +87,17 @@ func TestJsonEncode(t *testing.T) {
|
||||
// Sets
|
||||
testEncode(`j {"set":[]}
|
||||
`, NewSet())
|
||||
|
||||
// Blob (compound)
|
||||
blr := ref.MustParse("sha1-5bf524e621975ee2efbf02aed1bc0cd01f1cf8e0")
|
||||
cb := compoundBlob{uint64(2), []uint64{2}, []Future{futureFromRef(blr)}, &ref.Ref{}, s}
|
||||
testEncode(`j {"cb":[2,2,{"ref":"sha1-5bf524e621975ee2efbf02aed1bc0cd01f1cf8e0"}]}
|
||||
`, cb)
|
||||
|
||||
bl := newBlobLeaf([]byte("hello"))
|
||||
cb = compoundBlob{uint64(5), []uint64{5}, []Future{futureFromValue(bl)}, &ref.Ref{}, s}
|
||||
testEncode(`j {"cb":[5,5,{"ref":"sha1-8543a1b775237567a8c0e70e8ae7a1c6aac0ebbb"}]}
|
||||
`, cb)
|
||||
}
|
||||
|
||||
func TestGetJSONChildResolvedFuture(t *testing.T) {
|
||||
@@ -143,3 +155,26 @@ func TestFutureCompound(t *testing.T) {
|
||||
assert.IsType([]interface{}{}, m.(map[string]interface{})["map"])
|
||||
assert.Equal(0, cs.Reads)
|
||||
}
|
||||
|
||||
func TestCompoundBlobCodecChunked(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := &chunks.MemoryStore{}
|
||||
|
||||
f, err := os.Open("alice-short.txt")
|
||||
assert.NoError(err)
|
||||
defer f.Close()
|
||||
|
||||
b, err := NewBlob(f)
|
||||
assert.NoError(err)
|
||||
cb, ok := b.(compoundBlob)
|
||||
assert.True(ok)
|
||||
|
||||
r, err := jsonEncode(cb, cs)
|
||||
assert.Equal("sha1-a50d4c424c6221897e0b673ea9ed7769b8e83d49", r.String())
|
||||
|
||||
reader, err := cs.Get(r)
|
||||
assert.NoError(err)
|
||||
v, err := jsonDecode(reader, cs)
|
||||
assert.NoError(err)
|
||||
assert.True(cb.Equals(v))
|
||||
}
|
||||
|
||||
@@ -135,6 +135,8 @@ func TestMapEquals(t *testing.T) {
|
||||
|
||||
func TestMapNotStringKeys(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
b1, _ := NewBlob(bytes.NewBufferString("blob1"))
|
||||
b2, _ := NewBlob(bytes.NewBufferString("blob2"))
|
||||
l := []Value{
|
||||
Bool(true), NewString("true"),
|
||||
Bool(false), NewString("false"),
|
||||
@@ -142,8 +144,8 @@ func TestMapNotStringKeys(t *testing.T) {
|
||||
Int32(0), NewString("int32: 0"),
|
||||
Float64(1), NewString("float64: 1"),
|
||||
Float64(0), NewString("float64: 0"),
|
||||
NewBlob(bytes.NewBufferString("blob1")), NewString("blob1"),
|
||||
NewBlob(bytes.NewBufferString("blob2")), NewString("blob2"),
|
||||
b1, NewString("blob1"),
|
||||
b2, NewString("blob2"),
|
||||
NewList(), NewString("empty list"),
|
||||
NewList(NewList()), NewString("list of list"),
|
||||
NewMap(), NewString("empty map"),
|
||||
|
||||
@@ -35,7 +35,7 @@ func ReadValue(ref ref.Ref, cs chunks.ChunkSource) (Value, error) {
|
||||
}
|
||||
|
||||
if bytes.Equal(prefix, blobTag) {
|
||||
return blobDecode(buffered, cs)
|
||||
return blobLeafDecode(buffered, cs)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Unsupported chunk tag: %+v", prefix)
|
||||
|
||||
@@ -15,7 +15,7 @@ func NewString(s string) String {
|
||||
return String{s, &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (fs String) Blob() Blob {
|
||||
func (fs String) Blob() (Blob, error) {
|
||||
return NewBlob(bytes.NewBufferString(fs.s))
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,10 @@ import (
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
// TODO: This ends up loading the entire value recursively. We need to change the encoder to look at the futures directly and not expand them.
|
||||
func WriteValue(v Value, cs chunks.ChunkSink) (ref.Ref, error) {
|
||||
switch v := v.(type) {
|
||||
case Blob:
|
||||
return blobEncode(v, cs)
|
||||
case blobLeaf:
|
||||
return blobLeafEncode(v, cs)
|
||||
default:
|
||||
return jsonEncode(v, cs)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,9 @@ func TestWriteValue(t *testing.T) {
|
||||
|
||||
// Encoding details for each codec is tested elsewhere.
|
||||
// Here we just want to make sure codecs are selected correctly.
|
||||
testEncode(string([]byte{'b', ' ', 0x00, 0x01, 0x02}), NewBlob(bytes.NewBuffer([]byte{0x00, 0x01, 0x02})))
|
||||
b, err := NewBlob(bytes.NewBuffer([]byte{0x00, 0x01, 0x02}))
|
||||
assert.NoError(err)
|
||||
testEncode(string([]byte{'b', ' ', 0x00, 0x01, 0x02}), b)
|
||||
testEncode(string("j \"foo\"\n"), NewString("foo"))
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user