PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 131
// Copyright (C) MongoDB, Inc. 2017-present. // // Licensed under the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 package gridfs import ( "context" "errors" "io" "math" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" ) // ErrWrongIndex is used when the chunk retrieved from the server does not have the expected index. var ErrWrongIndex = errors.New("chunk index does not match expected index") // ErrWrongSize is used when the chunk retrieved from the server does not have the expected size. var ErrWrongSize = errors.New("chunk size does not match expected size") var errNoMoreChunks = errors.New("no more chunks remaining") // DownloadStream is a io.Reader that can be used to download a file from a GridFS bucket. type DownloadStream struct { numChunks int32 chunkSize int32 cursor *mongo.Cursor done bool closed bool buffer []byte // store up to 1 chunk if the user provided buffer isn't big enough bufferStart int bufferEnd int expectedChunk int32 // index of next expected chunk readDeadline time.Time fileLen int64 // The pointer returned by GetFile. This should not be used in the actual DownloadStream code outside of the // newDownloadStream constructor because the values can be mutated by the user after calling GetFile. Instead, // any values needed in the code should be stored separately and copied over in the constructor. file *File } // File represents a file stored in GridFS. This type can be used to access file information when downloading using the // DownloadStream.GetFile method. type File struct { // ID is the file's ID. This will match the file ID specified when uploading the file. If an upload helper that // does not require a file ID was used, this field will be a primitive.ObjectID. ID interface{} // Length is the length of this file in bytes. Length int64 // ChunkSize is the maximum number of bytes for each chunk in this file. ChunkSize int32 // UploadDate is the time this file was added to GridFS in UTC. This field is set by the driver and is not configurable. // The Metadata field can be used to store a custom date. UploadDate time.Time // Name is the name of this file. Name string // Metadata is additional data that was specified when creating this file. This field can be unmarshalled into a // custom type using the bson.Unmarshal family of functions. Metadata bson.Raw } var _ bson.Unmarshaler = (*File)(nil) // unmarshalFile is a temporary type used to unmarshal documents from the files collection and can be transformed into // a File instance. This type exists to avoid adding BSON struct tags to the exported File type. type unmarshalFile struct { ID interface{} `bson:"_id"` Length int64 `bson:"length"` ChunkSize int32 `bson:"chunkSize"` UploadDate time.Time `bson:"uploadDate"` Name string `bson:"filename"` Metadata bson.Raw `bson:"metadata"` } // UnmarshalBSON implements the bson.Unmarshaler interface. // // Deprecated: Unmarshaling a File from BSON will not be supported in Go Driver 2.0. func (f *File) UnmarshalBSON(data []byte) error { var temp unmarshalFile if err := bson.Unmarshal(data, &temp); err != nil { return err } f.ID = temp.ID f.Length = temp.Length f.ChunkSize = temp.ChunkSize f.UploadDate = temp.UploadDate f.Name = temp.Name f.Metadata = temp.Metadata return nil } func newDownloadStream(cursor *mongo.Cursor, chunkSize int32, file *File) *DownloadStream { numChunks := int32(math.Ceil(float64(file.Length) / float64(chunkSize))) return &DownloadStream{ numChunks: numChunks, chunkSize: chunkSize, cursor: cursor, buffer: make([]byte, chunkSize), done: cursor == nil, fileLen: file.Length, file: file, } } // Close closes this download stream. func (ds *DownloadStream) Close() error { if ds.closed { return ErrStreamClosed } ds.closed = true if ds.cursor != nil { return ds.cursor.Close(context.Background()) } return nil } // SetReadDeadline sets the read deadline for this download stream. func (ds *DownloadStream) SetReadDeadline(t time.Time) error { if ds.closed { return ErrStreamClosed } ds.readDeadline = t return nil } // Read reads the file from the server and writes it to a destination byte slice. func (ds *DownloadStream) Read(p []byte) (int, error) { if ds.closed { return 0, ErrStreamClosed } if ds.done { return 0, io.EOF } ctx, cancel := deadlineContext(ds.readDeadline) if cancel != nil { defer cancel() } bytesCopied := 0 var err error for bytesCopied < len(p) { if ds.bufferStart >= ds.bufferEnd { // Buffer is empty and can load in data from new chunk. err = ds.fillBuffer(ctx) if err != nil { if err == errNoMoreChunks { if bytesCopied == 0 { ds.done = true return 0, io.EOF } return bytesCopied, nil } return bytesCopied, err } } copied := copy(p[bytesCopied:], ds.buffer[ds.bufferStart:ds.bufferEnd]) bytesCopied += copied ds.bufferStart += copied } return len(p), nil } // Skip skips a given number of bytes in the file. func (ds *DownloadStream) Skip(skip int64) (int64, error) { if ds.closed { return 0, ErrStreamClosed } if ds.done { return 0, nil } ctx, cancel := deadlineContext(ds.readDeadline) if cancel != nil { defer cancel() } var skipped int64 var err error for skipped < skip { if ds.bufferStart >= ds.bufferEnd { // Buffer is empty and can load in data from new chunk. err = ds.fillBuffer(ctx) if err != nil { if err == errNoMoreChunks { return skipped, nil } return skipped, err } } toSkip := skip - skipped // Cap the amount to skip to the remaining bytes in the buffer to be consumed. bufferRemaining := ds.bufferEnd - ds.bufferStart if toSkip > int64(bufferRemaining) { toSkip = int64(bufferRemaining) } skipped += toSkip ds.bufferStart += int(toSkip) } return skip, nil } // GetFile returns a File object representing the file being downloaded. func (ds *DownloadStream) GetFile() *File { return ds.file } func (ds *DownloadStream) fillBuffer(ctx context.Context) error { if !ds.cursor.Next(ctx) { ds.done = true // Check for cursor error, otherwise there are no more chunks. if ds.cursor.Err() != nil { _ = ds.cursor.Close(ctx) return ds.cursor.Err() } // If there are no more chunks, but we didn't read the expected number of chunks, return an // ErrWrongIndex error to indicate that we're missing chunks at the end of the file. if ds.expectedChunk != ds.numChunks { return ErrWrongIndex } return errNoMoreChunks } chunkIndex, err := ds.cursor.Current.LookupErr("n") if err != nil { return err } var chunkIndexInt32 int32 if chunkIndexInt64, ok := chunkIndex.Int64OK(); ok { chunkIndexInt32 = int32(chunkIndexInt64) } else { chunkIndexInt32 = chunkIndex.Int32() } if chunkIndexInt32 != ds.expectedChunk { return ErrWrongIndex } ds.expectedChunk++ data, err := ds.cursor.Current.LookupErr("data") if err != nil { return err } _, dataBytes := data.Binary() copied := copy(ds.buffer, dataBytes) bytesLen := int32(len(dataBytes)) if ds.expectedChunk == ds.numChunks { // final chunk can be fewer than ds.chunkSize bytes bytesDownloaded := int64(ds.chunkSize) * (int64(ds.expectedChunk) - int64(1)) bytesRemaining := ds.fileLen - bytesDownloaded if int64(bytesLen) != bytesRemaining { return ErrWrongSize } } else if bytesLen != ds.chunkSize { // all intermediate chunks must have size ds.chunkSize return ErrWrongSize } ds.bufferStart = 0 ds.bufferEnd = copied return nil }